From 8f01dfad8cb6ad7555965384d95edad6708d49b3 Mon Sep 17 00:00:00 2001 From: Ali Mohammad Pur Date: Sun, 5 Nov 2023 18:59:19 +0330 Subject: [PATCH] Everywhere: Run prettier on everything This commit also brings in the prettierrc file from serenity proper. --- .prettierrc | 13 + index.html | 60 +-- repl/index.html | 141 ++++--- repl/main.js | 100 +++-- repl/repl.js | 336 ++++++++--------- test262/fetch.js | 13 +- test262/per-file/index.html | 189 +++++----- test262/per-file/main.js | 706 ++++++++++++++++++------------------ test262/test-config.js | 68 ++-- wasm/index.html | 283 +++++++-------- wasm/main.js | 667 +++++++++++++++++----------------- wasm/per-file/index.html | 198 +++++----- 12 files changed, 1342 insertions(+), 1432 deletions(-) create mode 100644 .prettierrc diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..ea15322 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,13 @@ +{ + "arrowParens": "avoid", + "bracketSpacing": true, + "endOfLine": "lf", + "insertPragma": false, + "printWidth": 100, + "quoteProps": "as-needed", + "semi": true, + "singleQuote": false, + "tabWidth": 4, + "trailingComma": "es5", + "useTabs": false +} diff --git a/index.html b/index.html index 32aa075..10fe23b 100644 --- a/index.html +++ b/index.html @@ -1,37 +1,37 @@ - + - - - - LibJS JavaScript engine - - - + code a, + code a:active, + code a:visited { + color: inherit; + } + + - -
// Website for SerenityOS's JavaScript engine, LibJS.
+    
+        
// Website for SerenityOS's JavaScript engine, LibJS.
 //
 // For details visit https://github.com/SerenityOS/serenity.
 //
@@ -42,5 +42,5 @@
 //
 // If you're a SerenityOS contributor and want to change something
 // here, open a PR in this repository.
- + diff --git a/repl/index.html b/repl/index.html index 8e77a8a..428e7c3 100644 --- a/repl/index.html +++ b/repl/index.html @@ -1,78 +1,71 @@ - + - - - - LibJS REPL - - - - - - + + + + LibJS REPL + + + + + + - -
-

LibJS REPL

-
- - - - - - - - - +
+ Loading... + +
+ + + + + + + + + + diff --git a/repl/main.js b/repl/main.js index 2f65ae2..d539d17 100644 --- a/repl/main.js +++ b/repl/main.js @@ -1,7 +1,5 @@ const inputTemplate = document.getElementById("repl-input-template"); -const staticInputTemplate = document.getElementById( - "repl-static-input-template" -); +const staticInputTemplate = document.getElementById("repl-static-input-template"); const outputTemplate = document.getElementById("repl-output-template"); const inputElement = document.getElementById("input"); const inputTextArea = inputElement.querySelector("textarea"); @@ -13,59 +11,59 @@ const loadingProgress = document.getElementById("loading-progress"); const headerDescriptionSpan = document.getElementById("header-description"); (async function () { - function updateLoading(name, { loaded, total, known }) { - loadingText.innerText = `Loading ${name}...`; - if (known) { - loadingProgress.max = total; - loadingProgress.value = loaded; - } else { - delete loadingProgress.max; - delete loadingProgress.value; + function updateLoading(name, { loaded, total, known }) { + loadingText.innerText = `Loading ${name}...`; + if (known) { + loadingProgress.max = total; + loadingProgress.value = loaded; + } else { + delete loadingProgress.max; + delete loadingProgress.value; + } } - } - const repl = await createREPL({ - inputTemplate, - staticInputTemplate, - outputTemplate, - inputElement, - inputTextArea, - outputElement, - updateLoading, - }); + const repl = await createREPL({ + inputTemplate, + staticInputTemplate, + outputTemplate, + inputElement, + inputTextArea, + outputElement, + updateLoading, + }); - const buildHash = Module.SERENITYOS_COMMIT; - const shortenedBuildHash = buildHash.substring(0, 7); - headerDescriptionSpan.innerHTML = ` (built from ${shortenedBuildHash})`; + const buildHash = Module.SERENITYOS_COMMIT; + const shortenedBuildHash = buildHash.substring(0, 7); + headerDescriptionSpan.innerHTML = ` (built from ${shortenedBuildHash})`; - loadingContainer.style.display = "none"; - mainContainer.style.display = ""; + loadingContainer.style.display = "none"; + mainContainer.style.display = ""; - repl.display("Ready!"); - inputTextArea.focus(); + repl.display("Ready!"); + inputTextArea.focus(); - const inputToggleButton = document.getElementById("input-toggle"); - const inputEditorTip = document.getElementById("input-editor-tip"); - const inputTip = document.getElementById("input-tip"); + const inputToggleButton = document.getElementById("input-toggle"); + const inputEditorTip = document.getElementById("input-editor-tip"); + const inputTip = document.getElementById("input-tip"); - inputToggleButton.addEventListener("click", () => { - if (inputToggleButton.classList.contains("input-shown")) { - inputToggleButton.classList.remove("input-shown"); - inputToggleButton.classList.add("input-hidden"); - inputToggleButton.textContent = ">"; - inputElement.style.display = "none"; - inputEditorTip.style.display = "none"; - inputTip.style.display = ""; - repl.allowDirectInput(); - } else { - inputToggleButton.classList.remove("input-hidden"); - inputToggleButton.classList.add("input-shown"); - inputToggleButton.textContent = "<"; - inputElement.style.display = ""; - inputEditorTip.style.display = ""; - inputTip.style.display = "none"; - repl.prohibitDirectInput(); - inputTextArea.focus(); - } - }); + inputToggleButton.addEventListener("click", () => { + if (inputToggleButton.classList.contains("input-shown")) { + inputToggleButton.classList.remove("input-shown"); + inputToggleButton.classList.add("input-hidden"); + inputToggleButton.textContent = ">"; + inputElement.style.display = "none"; + inputEditorTip.style.display = "none"; + inputTip.style.display = ""; + repl.allowDirectInput(); + } else { + inputToggleButton.classList.remove("input-hidden"); + inputToggleButton.classList.add("input-shown"); + inputToggleButton.textContent = "<"; + inputElement.style.display = ""; + inputEditorTip.style.display = ""; + inputTip.style.display = "none"; + repl.prohibitDirectInput(); + inputTextArea.focus(); + } + }); })(); diff --git a/repl/repl.js b/repl/repl.js index 7e65827..f72c6cb 100644 --- a/repl/repl.js +++ b/repl/repl.js @@ -1,187 +1,171 @@ -if (typeof Module === "undefined") - throw new Error("LibJS.js must be loaded before repl.js"); +if (typeof Module === "undefined") throw new Error("LibJS.js must be loaded before repl.js"); function globalDisplayToUser(text) { - globalDisplayToUser.repl.push(text); + globalDisplayToUser.repl.push(text); } async function createREPL(elements) { - const repl = Object.create(null); - elements.updateLoading("LibJS Runtime", { known: false }); - - await new Promise((resolve) => addOnPostRun(resolve)); - - elements.updateLoading("LibJS WebAssembly Module", { known: false }); - if (!runtimeInitialized) { - initRuntime(); - } - - // The REPL only has access to a limited, virtual file system that does not contain time zone - // information. Retrieve the current time zone from the running browser for LibJS to use. - let timeZone; - - try { - const dateTimeFormat = new Intl.DateTimeFormat(); - timeZone = Module.allocateUTF8(dateTimeFormat.resolvedOptions().timeZone); - } catch { - timeZone = Module.allocateUTF8("UTC"); - } - - if (Module._initialize_repl(timeZone) !== 0) - throw new Error("Failed to initialize REPL"); - - Module._free(timeZone); - - repl.private = { - allowingDirectInput: false, - activeInputs: [], - inactiveInputs: [], - outputs: [], - prepareInput() { - let node = elements.inputTemplate.content.children[0].cloneNode(true); - return repl.private.attachInput(node, { directly: true }); - }, - prepareOutput() { - let node = elements.outputTemplate.cloneNode(true).content.children[0]; - node = elements.outputElement.appendChild(node); - node.addEventListener("mouseenter", () => { - if (!node._input) return; - - node._input.classList.add("hovered-related"); - node._input._related.forEach((other) => { - other.classList.add("hovered-related"); - }); - }); - node.addEventListener("mouseleave", () => { - if (!node._input) return; + const repl = Object.create(null); + elements.updateLoading("LibJS Runtime", { known: false }); - node._input.classList.remove("hovered-related"); - node._input._related.forEach((other) => { - other.classList.remove("hovered-related"); - }); - }); - return node; - }, - attachInput(node, { directly }) { - if (directly) { - node = elements.outputElement.appendChild(node); - node._isDirect = true; - } - node._related = []; - const editor = node.querySelector("textarea"); - editor.addEventListener("keydown", (event) => { - const requireCtrl = directly; - if (event.keyCode == 13 && requireCtrl ^ event.ctrlKey) { - event.preventDefault(); - repl.execute(node, editor.value); - return false; - } - return true; - }); - document - .getElementById("run") - .addEventListener("onclick", () => repl.execute(node, editor.value)); - node.addEventListener("mouseenter", () => { - node._related.forEach((other) => { - other.classList.add("hovered-related"); - }); - }); - node.addEventListener("mouseleave", () => { - node._related.forEach((other) => { - other.classList.remove("hovered-related"); - }); - }); - return node; - }, - execute(text) { - const encodedText = Module.allocateUTF8(text); - let oldRepl = globalDisplayToUser.repl; - try { - globalDisplayToUser.repl = repl.private.outputs; - Module._execute(encodedText); - return repl.private.outputs; - } finally { - globalDisplayToUser.repl = oldRepl; - repl.private.outputs = []; - Module._free(encodedText); - } - }, - markRelated(node, input) { - node._input = input; - input._related.push(node); - }, - }; - - repl.private.attachInput(elements.inputElement, { directly: false }); - - repl.display = (text, relatedInput = null) => { - text.split("\n").forEach((line) => { - const node = repl.private.prepareOutput(); - node.querySelector("pre").textContent = line; - if (relatedInput !== null) { - repl.private.markRelated(node, relatedInput); - } - }); - }; - repl.allowDirectInput = () => { - repl.private.allowingDirectInput = true; - repl.private.inactiveInputs.forEach((node) => - repl.private.attachInput(node, { directly: true }) - ); - repl.private.activeInputs = repl.private.inactiveInputs; - repl.private.inactiveInputs = []; - if ( - repl.private.allowingDirectInput && - repl.private.activeInputs.length == 0 - ) { - repl.addInput(); - } - }; - repl.prohibitDirectInput = () => { - repl.private.allowingDirectInput = false; - repl.private.activeInputs.forEach((node) => node.remove()); - repl.private.inactiveInputs = repl.private.inactiveInputs.concat( - repl.private.activeInputs - ); - repl.private.activeInputs = []; - }; - repl.addInput = () => { - const input = repl.private.prepareInput(); - repl.private.activeInputs.push(input); - input.querySelector("textarea").focus(); - }; - repl.addStaticInput = (text) => { - const input = - elements.staticInputTemplate.cloneNode(true).content.children[0]; - input.querySelector("pre.content").textContent = text; - input._related = []; - return elements.outputElement.appendChild(input); - }; - repl.execute = (input, text) => { - repl.private.activeInputs = repl.private.activeInputs.filter( - (i) => i !== input - ); - let staticInput = repl.addStaticInput(text); - let outputs = repl.private.execute(text).join(""); - if (outputs.endsWith("undefined\n")) - outputs = outputs.substring(0, outputs.length - 10); - - repl.display(outputs, input); - - input._related.forEach((node) => - repl.private.markRelated(node, staticInput) - ); - if (input._isDirect) { - input.remove(); + await new Promise(resolve => addOnPostRun(resolve)); + + elements.updateLoading("LibJS WebAssembly Module", { known: false }); + if (!runtimeInitialized) { + initRuntime(); } - if ( - repl.private.allowingDirectInput && - repl.private.activeInputs.length == 0 - ) { - repl.addInput(); + // The REPL only has access to a limited, virtual file system that does not contain time zone + // information. Retrieve the current time zone from the running browser for LibJS to use. + let timeZone; + + try { + const dateTimeFormat = new Intl.DateTimeFormat(); + timeZone = Module.allocateUTF8(dateTimeFormat.resolvedOptions().timeZone); + } catch { + timeZone = Module.allocateUTF8("UTC"); } - }; - return repl; + if (Module._initialize_repl(timeZone) !== 0) throw new Error("Failed to initialize REPL"); + + Module._free(timeZone); + + repl.private = { + allowingDirectInput: false, + activeInputs: [], + inactiveInputs: [], + outputs: [], + prepareInput() { + let node = elements.inputTemplate.content.children[0].cloneNode(true); + return repl.private.attachInput(node, { directly: true }); + }, + prepareOutput() { + let node = elements.outputTemplate.cloneNode(true).content.children[0]; + node = elements.outputElement.appendChild(node); + node.addEventListener("mouseenter", () => { + if (!node._input) return; + + node._input.classList.add("hovered-related"); + node._input._related.forEach(other => { + other.classList.add("hovered-related"); + }); + }); + node.addEventListener("mouseleave", () => { + if (!node._input) return; + + node._input.classList.remove("hovered-related"); + node._input._related.forEach(other => { + other.classList.remove("hovered-related"); + }); + }); + return node; + }, + attachInput(node, { directly }) { + if (directly) { + node = elements.outputElement.appendChild(node); + node._isDirect = true; + } + node._related = []; + const editor = node.querySelector("textarea"); + editor.addEventListener("keydown", event => { + const requireCtrl = directly; + if (event.keyCode == 13 && requireCtrl ^ event.ctrlKey) { + event.preventDefault(); + repl.execute(node, editor.value); + return false; + } + return true; + }); + document + .getElementById("run") + .addEventListener("onclick", () => repl.execute(node, editor.value)); + node.addEventListener("mouseenter", () => { + node._related.forEach(other => { + other.classList.add("hovered-related"); + }); + }); + node.addEventListener("mouseleave", () => { + node._related.forEach(other => { + other.classList.remove("hovered-related"); + }); + }); + return node; + }, + execute(text) { + const encodedText = Module.allocateUTF8(text); + let oldRepl = globalDisplayToUser.repl; + try { + globalDisplayToUser.repl = repl.private.outputs; + Module._execute(encodedText); + return repl.private.outputs; + } finally { + globalDisplayToUser.repl = oldRepl; + repl.private.outputs = []; + Module._free(encodedText); + } + }, + markRelated(node, input) { + node._input = input; + input._related.push(node); + }, + }; + + repl.private.attachInput(elements.inputElement, { directly: false }); + + repl.display = (text, relatedInput = null) => { + text.split("\n").forEach(line => { + const node = repl.private.prepareOutput(); + node.querySelector("pre").textContent = line; + if (relatedInput !== null) { + repl.private.markRelated(node, relatedInput); + } + }); + }; + repl.allowDirectInput = () => { + repl.private.allowingDirectInput = true; + repl.private.inactiveInputs.forEach(node => + repl.private.attachInput(node, { directly: true }) + ); + repl.private.activeInputs = repl.private.inactiveInputs; + repl.private.inactiveInputs = []; + if (repl.private.allowingDirectInput && repl.private.activeInputs.length == 0) { + repl.addInput(); + } + }; + repl.prohibitDirectInput = () => { + repl.private.allowingDirectInput = false; + repl.private.activeInputs.forEach(node => node.remove()); + repl.private.inactiveInputs = repl.private.inactiveInputs.concat(repl.private.activeInputs); + repl.private.activeInputs = []; + }; + repl.addInput = () => { + const input = repl.private.prepareInput(); + repl.private.activeInputs.push(input); + input.querySelector("textarea").focus(); + }; + repl.addStaticInput = text => { + const input = elements.staticInputTemplate.cloneNode(true).content.children[0]; + input.querySelector("pre.content").textContent = text; + input._related = []; + return elements.outputElement.appendChild(input); + }; + repl.execute = (input, text) => { + repl.private.activeInputs = repl.private.activeInputs.filter(i => i !== input); + let staticInput = repl.addStaticInput(text); + let outputs = repl.private.execute(text).join(""); + if (outputs.endsWith("undefined\n")) outputs = outputs.substring(0, outputs.length - 10); + + repl.display(outputs, input); + + input._related.forEach(node => repl.private.markRelated(node, staticInput)); + if (input._isDirect) { + input.remove(); + } + + if (repl.private.allowingDirectInput && repl.private.activeInputs.length == 0) { + repl.addInput(); + } + }; + + return repl; } diff --git a/test262/fetch.js b/test262/fetch.js index b951e3d..2dd537a 100644 --- a/test262/fetch.js +++ b/test262/fetch.js @@ -1,9 +1,8 @@ -const LIBJS_DATA_URL = - "https://raw.githubusercontent.com/SerenityOS/libjs-data/master"; +const LIBJS_DATA_URL = "https://raw.githubusercontent.com/SerenityOS/libjs-data/master"; -const fetchData = (path) => { - return fetch(`${LIBJS_DATA_URL}/${path}`, { - method: "GET", - cache: "no-cache", - }); +const fetchData = path => { + return fetch(`${LIBJS_DATA_URL}/${path}`, { + method: "GET", + cache: "no-cache", + }); }; diff --git a/test262/per-file/index.html b/test262/per-file/index.html index c016002..11a6dba 100644 --- a/test262/per-file/index.html +++ b/test262/per-file/index.html @@ -1,107 +1,90 @@ - + - - - - LibJS test262 per-file results - - - - - - + + + + LibJS test262 per-file results + + + + + + - -
-
- - -

Per-file results

-
- Loading... -
- -
-
-
-
    -
    - - - - - - + +
    +
    + + +

    Per-file results

    +
    + Loading... +
    + +
    +
    +
    +
      +
      + + + + + + - - - + + + diff --git a/test262/per-file/main.js b/test262/per-file/main.js index 02f3d76..fc589c0 100644 --- a/test262/per-file/main.js +++ b/test262/per-file/main.js @@ -9,17 +9,17 @@ let summaryLabel; let summaryStatusLabel; let leafTreeNodeTemplate; let nonLeafTreeNodeTemplate; -let pathInTree = new URL(location.href).searchParams - .get("path") - ?.split("/") ?? [...initialPathInTree]; +let pathInTree = new URL(location.href).searchParams.get("path")?.split("/") ?? [ + ...initialPathInTree, +]; let tree; const resultsObject = Object.create(null); const legendResults = [ - TestResult.PASSED, - TestResult.FAILED, - TestResult.PROCESS_ERROR, - TestResult.TODO_ERROR, + TestResult.PASSED, + TestResult.FAILED, + TestResult.PROCESS_ERROR, + TestResult.TODO_ERROR, ]; const shownResultTypes = new Set(Object.values(TestResult)); @@ -31,440 +31,426 @@ let filtering = false; // Click circle -> show only that one function initialize(data, modeName) { - let mode = modeName; - - // Do a pass and generate the tree. - for (const testPath in data.results) { - const segments = testPath.split("/"); - const fileName = segments.pop(); - let testObject = resultsObject; - for (const pathSegment of segments) { - if (!(pathSegment in testObject)) { - testObject[pathSegment] = { - children: Object.create(null), - aggregatedResults: null, - }; - } + let mode = modeName; + + // Do a pass and generate the tree. + for (const testPath in data.results) { + const segments = testPath.split("/"); + const fileName = segments.pop(); + let testObject = resultsObject; + for (const pathSegment of segments) { + if (!(pathSegment in testObject)) { + testObject[pathSegment] = { + children: Object.create(null), + aggregatedResults: null, + }; + } - testObject = testObject[pathSegment].children; - } + testObject = testObject[pathSegment].children; + } - if (!(fileName in testObject)) { - testObject[fileName] = { - children: null, - results: Object.create(null), - }; - } + if (!(fileName in testObject)) { + testObject[fileName] = { + children: null, + results: Object.create(null), + }; + } - testObject[fileName].results[mode] = data.results[testPath].toLowerCase(); - } + testObject[fileName].results[mode] = data.results[testPath].toLowerCase(); + } } function generateResults() { - function constructTree(results) { - if (results.children === null) { - results.aggregatedResults = Object.fromEntries( - Object.keys(results.results).map((name) => [ - name, - { [results.results[name]]: 1 }, - ]) - ); - - return; - } + function constructTree(results) { + if (results.children === null) { + results.aggregatedResults = Object.fromEntries( + Object.keys(results.results).map(name => [name, { [results.results[name]]: 1 }]) + ); - for (const name in results.children) { - constructTree(results.children[name]); - } + return; + } + + for (const name in results.children) { + constructTree(results.children[name]); + } - for (const name in results.children) { - const childResults = results.children[name]; - results.aggregatedResults = Object.keys( - childResults.aggregatedResults - ).reduce((acc, mode) => { - if (!(mode in acc)) acc[mode] = {}; - const modeAcc = acc[mode]; - const stats = childResults.aggregatedResults[mode]; - for (const name in stats) { - if (name in modeAcc) modeAcc[name] += stats[name]; - else modeAcc[name] = stats[name]; + for (const name in results.children) { + const childResults = results.children[name]; + results.aggregatedResults = Object.keys(childResults.aggregatedResults).reduce( + (acc, mode) => { + if (!(mode in acc)) acc[mode] = {}; + const modeAcc = acc[mode]; + const stats = childResults.aggregatedResults[mode]; + for (const name in stats) { + if (name in modeAcc) modeAcc[name] += stats[name]; + else modeAcc[name] = stats[name]; + } + return acc; + }, + results.aggregatedResults || {} + ); } - return acc; - }, results.aggregatedResults || {}); } - } - - // Now do another pass and aggregate the results. - let results = { - children: resultsObject, - aggregatedResults: {}, - }; - constructTree(results); - tree = results; - - resultsNode = document.getElementById("results"); - legendNode = document.getElementById("legend"); - searchInputNode = document.getElementById("search-input"); - summaryLabel = document.getElementById("summary"); - summaryStatusLabel = document.getElementById("summary-status"); - leafTreeNodeTemplate = document.getElementById("leaf-tree-node-template"); - nonLeafTreeNodeTemplate = document.getElementById( - "nonleaf-tree-node-template" - ); - - // Now make a nice lazy-loaded collapsible tree in `resultsNode`. - regenerateResults(resultsNode); - - summaryStatusLabel.classList.remove("hidden"); - - legendNode.innerHTML = legendResults - .map((result) => { - const color = TestResultColors[result]; - const label = TestResultLabels[result]; - return ` + + // Now do another pass and aggregate the results. + let results = { + children: resultsObject, + aggregatedResults: {}, + }; + constructTree(results); + tree = results; + + resultsNode = document.getElementById("results"); + legendNode = document.getElementById("legend"); + searchInputNode = document.getElementById("search-input"); + summaryLabel = document.getElementById("summary"); + summaryStatusLabel = document.getElementById("summary-status"); + leafTreeNodeTemplate = document.getElementById("leaf-tree-node-template"); + nonLeafTreeNodeTemplate = document.getElementById("nonleaf-tree-node-template"); + + // Now make a nice lazy-loaded collapsible tree in `resultsNode`. + regenerateResults(resultsNode); + + summaryStatusLabel.classList.remove("hidden"); + + legendNode.innerHTML = legendResults + .map(result => { + const color = TestResultColors[result]; + const label = TestResultLabels[result]; + return ` ${label} `; - }) - .join(" "); - - function legendChanged() { - legendNode.querySelectorAll(".legend-item").forEach((legendItem) => { - if (shownResultTypes.has(legendItem.getAttribute("data-type"))) - legendItem.style.textDecoration = null; - else legendItem.style.textDecoration = "line-through"; + }) + .join(" "); + + function legendChanged() { + legendNode.querySelectorAll(".legend-item").forEach(legendItem => { + if (shownResultTypes.has(legendItem.getAttribute("data-type"))) + legendItem.style.textDecoration = null; + else legendItem.style.textDecoration = "line-through"; + }); + } + + legendNode.querySelectorAll(".legend-item").forEach(legendItem => { + legendItem.onclick = event => { + const clickedCircle = event.target !== legendItem; + const resultType = legendItem.getAttribute("data-type"); + if (clickedCircle) { + if (shownResultTypes.size === 1 && shownResultTypes.has(resultType)) { + Object.values(TestResult).forEach(v => shownResultTypes.add(v)); + } else { + shownResultTypes.clear(); + shownResultTypes.add(resultType); + } + } else { + if (shownResultTypes.has(resultType)) { + shownResultTypes.delete(resultType); + } else { + shownResultTypes.add(resultType); + } + } + + legendChanged(); + regenerateResults(resultsNode); + }; }); - } - - legendNode.querySelectorAll(".legend-item").forEach((legendItem) => { - legendItem.onclick = (event) => { - const clickedCircle = event.target !== legendItem; - const resultType = legendItem.getAttribute("data-type"); - if (clickedCircle) { - if (shownResultTypes.size === 1 && shownResultTypes.has(resultType)) { - Object.values(TestResult).forEach((v) => shownResultTypes.add(v)); - } else { - shownResultTypes.clear(); - shownResultTypes.add(resultType); - } - } else { - if (shownResultTypes.has(resultType)) { - shownResultTypes.delete(resultType); - } else { - shownResultTypes.add(resultType); - } - } - legendChanged(); - regenerateResults(resultsNode); + searchInputNode.oninput = event => { + searchQuery = event.target.value.toLowerCase(); + regenerateResults(resultsNode); }; - }); - searchInputNode.oninput = (event) => { - searchQuery = event.target.value.toLowerCase(); - regenerateResults(resultsNode); - }; - - const filterModeCheckbox = document.getElementById("search-mode-checkbox"); - filterModeCheckbox.checked = filtering; - filterModeCheckbox.oninput = (event) => { - filtering = event.target.checked; - regenerateResults(resultsNode); - }; + const filterModeCheckbox = document.getElementById("search-mode-checkbox"); + filterModeCheckbox.checked = filtering; + filterModeCheckbox.oninput = event => { + filtering = event.target.checked; + regenerateResults(resultsNode); + }; - // We hide the search input and filter mode checkbox until the rest is loaded - document.getElementById("search").classList.remove("hidden"); - document.getElementById("search-mode").classList.remove("hidden"); + // We hide the search input and filter mode checkbox until the rest is loaded + document.getElementById("search").classList.remove("hidden"); + document.getElementById("search-mode").classList.remove("hidden"); } -window.onpopstate = (event) => { - pathInTree = event.state?.pathInTree ?? [...initialPathInTree]; - regenerateResults(resultsNode); +window.onpopstate = event => { + pathInTree = event.state?.pathInTree ?? [...initialPathInTree]; + regenerateResults(resultsNode); }; function navigate() { - if (!filtering) { - searchInputNode.value = ""; - searchQuery = ""; - } - history.pushState( - { pathInTree }, - pathInTree[pathInTree.length - 1], - generateQueryString(pathInTree) - ); - regenerateResults(resultsNode); + if (!filtering) { + searchInputNode.value = ""; + searchQuery = ""; + } + history.pushState( + { pathInTree }, + pathInTree[pathInTree.length - 1], + generateQueryString(pathInTree) + ); + regenerateResults(resultsNode); } function goToParentDirectory(count) { - for (let i = 0; i < count; ++i) { - pathInTree.pop(); - } - navigate(); + for (let i = 0; i < count; ++i) { + pathInTree.pop(); + } + navigate(); } function generateQueryString(pathSegments) { - return `?path=${pathSegments.join("/")}`; + return `?path=${pathSegments.join("/")}`; } function generateSummary(results) { - summaryLabel.innerHTML = "/ "; - for (let i = 0; i < pathInTree.length; ++i) { - const pathSegment = pathInTree[i]; - const pathSegmentLink = document.createElement("a"); - pathSegmentLink.textContent = pathSegment; - pathSegmentLink.href = generateQueryString(pathInTree.slice(0, i + 1)); - pathSegmentLink.onclick = (event) => { - if (event.metaKey || event.ctrlKey) return; - event.preventDefault(); - goToParentDirectory(pathInTree.length - i - 1); - }; - summaryLabel.appendChild(pathSegmentLink); - if (i < pathInTree.length - 1) { - summaryLabel.insertAdjacentHTML("beforeend", " / "); + summaryLabel.innerHTML = "/ "; + for (let i = 0; i < pathInTree.length; ++i) { + const pathSegment = pathInTree[i]; + const pathSegmentLink = document.createElement("a"); + pathSegmentLink.textContent = pathSegment; + pathSegmentLink.href = generateQueryString(pathInTree.slice(0, i + 1)); + pathSegmentLink.onclick = event => { + if (event.metaKey || event.ctrlKey) return; + event.preventDefault(); + goToParentDirectory(pathInTree.length - i - 1); + }; + summaryLabel.appendChild(pathSegmentLink); + if (i < pathInTree.length - 1) { + summaryLabel.insertAdjacentHTML("beforeend", " / "); + } } - } - summaryStatusLabel.innerHTML = generateStatus(results.aggregatedResults); + summaryStatusLabel.innerHTML = generateStatus(results.aggregatedResults); } function generateChildNode(childName, child, filepath) { - const template = - child.children === null ? leafTreeNodeTemplate : nonLeafTreeNodeTemplate; - const childNode = template.content.children[0].cloneNode(true); - childNode.querySelector(".tree-node-name").textContent = childName; - childNode.querySelector(".tree-node-name").title = filepath; - childNode.querySelector(".tree-node-status").innerHTML = generateStatus( - child.aggregatedResults - ); - childNode.querySelector(".tree-node-github-url").href = - window.config.generateGitHubURLFromTestPath(filepath); - return childNode; + const template = child.children === null ? leafTreeNodeTemplate : nonLeafTreeNodeTemplate; + const childNode = template.content.children[0].cloneNode(true); + childNode.querySelector(".tree-node-name").textContent = childName; + childNode.querySelector(".tree-node-name").title = filepath; + childNode.querySelector(".tree-node-status").innerHTML = generateStatus( + child.aggregatedResults + ); + childNode.querySelector(".tree-node-github-url").href = + window.config.generateGitHubURLFromTestPath(filepath); + return childNode; } function makeChildNavigable(childNode, extraPathParts) { - const actionNode = childNode.querySelector(".tree-node-action"); - - actionNode.href = generateQueryString([...pathInTree, ...extraPathParts]); - actionNode.onclick = function (event) { - if (event.metaKey || event.ctrlKey) return; - event.preventDefault(); - for (const part of extraPathParts) pathInTree.push(part); - navigate(); - }; + const actionNode = childNode.querySelector(".tree-node-action"); + + actionNode.href = generateQueryString([...pathInTree, ...extraPathParts]); + actionNode.onclick = function (event) { + if (event.metaKey || event.ctrlKey) return; + event.preventDefault(); + for (const part of extraPathParts) pathInTree.push(part); + navigate(); + }; } function sortResultsByTypeAndName([lhsName, lhsResult], [rhsName, rhsResult]) { - if ((lhsResult.children === null) === (rhsResult.children === null)) - return lhsName.localeCompare(rhsName); - return lhsResult.children === null ? 1 : -1; + if ((lhsResult.children === null) === (rhsResult.children === null)) + return lhsName.localeCompare(rhsName); + return lhsResult.children === null ? 1 : -1; } // Setting this to false means filters check both AST and BC. let checkASTOnly = true; function entryHasFilteredResultType([, child]) { - if (checkASTOnly && "AST" in child.aggregatedResults) { - return Object.keys(child.aggregatedResults.AST).some((type) => - shownResultTypes.has(type) - ); - } + if (checkASTOnly && "AST" in child.aggregatedResults) { + return Object.keys(child.aggregatedResults.AST).some(type => shownResultTypes.has(type)); + } - return Object.values(child.aggregatedResults).some((testType) => - Object.keys(testType).some((type) => shownResultTypes.has(type)) - ); + return Object.values(child.aggregatedResults).some(testType => + Object.keys(testType).some(type => shownResultTypes.has(type)) + ); } function regenerateResults(targetNode) { - const needle = searchQuery.length >= 3 ? searchQuery : ""; - - for (const child of Array.prototype.slice.call(targetNode.children)) { - child.remove(); - } - - const results = pathInTree.reduce((acc, x) => acc.children[x], tree); - generateSummary(results); - - let nodes; - if (!needle) { - nodes = Object.entries(results.children) - .filter(entryHasFilteredResultType) - .sort(sortResultsByTypeAndName) - .map(([childName, child]) => { - const childNode = generateChildNode( - childName, - child, - `${pathInTree.join("/")}/${childName}` - ); + const needle = searchQuery.length >= 3 ? searchQuery : ""; - const isLeaf = child.children === null; - if (!isLeaf) { - makeChildNavigable(childNode, [childName]); - } - return childNode; - }); - } else { - function searchResults(result, allChildren = false, extraPath = "") { - return Object.entries(result) - .filter(entryHasFilteredResultType) - .flatMap(([childName, child]) => { - const isLeaf = child.children === null; - - let isSearchedFor = childName.toLowerCase().includes(needle); - let relativePath = extraPath + childName; - if (isLeaf) { - if (isSearchedFor) return [[childName, child, relativePath]]; - else return []; - } - - const childrenResults = searchResults( - child.children, - false, - relativePath + "/" - ); - if (isSearchedFor) - childrenResults.push([childName, child, relativePath]); - - return childrenResults; - }) - .sort(sortResultsByTypeAndName); + for (const child of Array.prototype.slice.call(targetNode.children)) { + child.remove(); } - function filterResults(result) { - function filterInternal(result, allChildren = false, extraPath = "") { - return Object.entries(result) - .filter(entryHasFilteredResultType) - .map(([childName, child]) => { - const isLeaf = child.children === null; - - let isSearchedFor = childName.toLowerCase().includes(needle); - let relativePath = extraPath + childName; + const results = pathInTree.reduce((acc, x) => acc.children[x], tree); + generateSummary(results); + + let nodes; + if (!needle) { + nodes = Object.entries(results.children) + .filter(entryHasFilteredResultType) + .sort(sortResultsByTypeAndName) + .map(([childName, child]) => { + const childNode = generateChildNode( + childName, + child, + `${pathInTree.join("/")}/${childName}` + ); + + const isLeaf = child.children === null; + if (!isLeaf) { + makeChildNavigable(childNode, [childName]); + } + return childNode; + }); + } else { + function searchResults(result, allChildren = false, extraPath = "") { + return Object.entries(result) + .filter(entryHasFilteredResultType) + .flatMap(([childName, child]) => { + const isLeaf = child.children === null; + + let isSearchedFor = childName.toLowerCase().includes(needle); + let relativePath = extraPath + childName; + if (isLeaf) { + if (isSearchedFor) return [[childName, child, relativePath]]; + else return []; + } + + const childrenResults = searchResults( + child.children, + false, + relativePath + "/" + ); + if (isSearchedFor) childrenResults.push([childName, child, relativePath]); + + return childrenResults; + }) + .sort(sortResultsByTypeAndName); + } - if (isLeaf) { - if (isSearchedFor || allChildren) - return [childName, child, relativePath, null]; - return []; + function filterResults(result) { + function filterInternal(result, allChildren = false, extraPath = "") { + return Object.entries(result) + .filter(entryHasFilteredResultType) + .map(([childName, child]) => { + const isLeaf = child.children === null; + + let isSearchedFor = childName.toLowerCase().includes(needle); + let relativePath = extraPath + childName; + + if (isLeaf) { + if (isSearchedFor || allChildren) + return [childName, child, relativePath, null]; + return []; + } + const childrenResults = filterInternal( + child.children, + isSearchedFor, + relativePath + "/" + ); + if (!isSearchedFor && childrenResults.length === 0 && !allChildren) + return []; + + return [childName, child, relativePath, childrenResults]; + }) + .filter(i => i.length > 0) + .sort(sortResultsByTypeAndName); } - const childrenResults = filterInternal( - child.children, - isSearchedFor, - relativePath + "/" - ); - if (!isSearchedFor && childrenResults.length === 0 && !allChildren) - return []; - - return [childName, child, relativePath, childrenResults]; - }) - .filter((i) => i.length > 0) - .sort(sortResultsByTypeAndName); - } - - let results = filterInternal( - result, - pathInTree.join("/").toLowerCase().includes(needle) - ); - - while (results.length === 1 && results[0][3] !== null) - results = results[0][3]; - return results; - } + let results = filterInternal( + result, + pathInTree.join("/").toLowerCase().includes(needle) + ); - const maxResultsShown = 500; - const foundResults = filtering - ? filterResults(results.children) - : searchResults(results.children); - nodes = foundResults - .filter((_, i) => i < maxResultsShown) - .map(([childName, child, relativePath]) => { - const childNode = generateChildNode( - childName, - child, - `${pathInTree.join("/")}/${relativePath}` - ); + while (results.length === 1 && results[0][3] !== null) results = results[0][3]; - if (child.children !== null) { - const extraPathParts = [ - ...relativePath.split("/").filter((s) => s.length > 0), - ]; - makeChildNavigable(childNode, extraPathParts, targetNode); + return results; } - return childNode; - }); - - if (foundResults.length > maxResultsShown) { - const extraNode = document.createElement("p"); - extraNode.innerText = `Only show the first ${maxResultsShown} of ${foundResults.length} results.`; - extraNode.classList.add("search-warning"); - nodes.push(extraNode); + const maxResultsShown = 500; + const foundResults = filtering + ? filterResults(results.children) + : searchResults(results.children); + nodes = foundResults + .filter((_, i) => i < maxResultsShown) + .map(([childName, child, relativePath]) => { + const childNode = generateChildNode( + childName, + child, + `${pathInTree.join("/")}/${relativePath}` + ); + + if (child.children !== null) { + const extraPathParts = [...relativePath.split("/").filter(s => s.length > 0)]; + makeChildNavigable(childNode, extraPathParts, targetNode); + } + + return childNode; + }); + + if (foundResults.length > maxResultsShown) { + const extraNode = document.createElement("p"); + extraNode.innerText = `Only show the first ${maxResultsShown} of ${foundResults.length} results.`; + extraNode.classList.add("search-warning"); + nodes.push(extraNode); + } } - } - nodes.forEach((node) => targetNode.appendChild(node)); + nodes.forEach(node => targetNode.appendChild(node)); } function color(name) { - return TestResultColors[name] || "black"; + return TestResultColors[name] || "black"; } function resultAwareSort(names) { - const resultOrder = [ - TestResult.PASSED, - TestResult.FAILED, - TestResult.SKIPPED, - TestResult.PROCESS_ERROR, - TestResult.TODO_ERROR, - TestResult.METADATA_ERROR, - TestResult.HARNESS_ERROR, - TestResult.TIMEOUT_ERROR, - TestResult.RUNNER_EXCEPTION, - TestResult.DURATION, - ]; - - return names.sort((a, b) => { - const aIndex = resultOrder.indexOf(a); - const bIndex = resultOrder.indexOf(b); - return aIndex - bIndex; - }); + const resultOrder = [ + TestResult.PASSED, + TestResult.FAILED, + TestResult.SKIPPED, + TestResult.PROCESS_ERROR, + TestResult.TODO_ERROR, + TestResult.METADATA_ERROR, + TestResult.HARNESS_ERROR, + TestResult.TIMEOUT_ERROR, + TestResult.RUNNER_EXCEPTION, + TestResult.DURATION, + ]; + + return names.sort((a, b) => { + const aIndex = resultOrder.indexOf(a); + const bIndex = resultOrder.indexOf(b); + return aIndex - bIndex; + }); } function generateStatus(aggregatedResults) { - const status = Object.keys(aggregatedResults) - .sort() - .reduce((acc, mode) => { - const stats = aggregatedResults[mode]; - const total = Object.keys(stats).reduce( - (acc, name) => acc + stats[name], - 0 - ); - if (total === 0) return acc; - acc.push(`
      + const status = Object.keys(aggregatedResults) + .sort() + .reduce((acc, mode) => { + const stats = aggregatedResults[mode]; + const total = Object.keys(stats).reduce((acc, name) => acc + stats[name], 0); + if (total === 0) return acc; + acc.push(`
      ${mode}
      ${resultAwareSort(Object.keys(stats)) - .map((x) => { - const percentTotal = ((100 * stats[x]) / total).toFixed(2); - const toolTip = `${TestResultLabels[x]}: ${stats[x]} / ${total} (${percentTotal}%)`; - const barColor = color(x); - return `
      `; - }) - .join("")} + .map(x => { + const percentTotal = ((100 * stats[x]) / total).toFixed(2); + const toolTip = `${TestResultLabels[x]}: ${stats[x]} / ${total} (${percentTotal}%)`; + const barColor = color(x); + return `
      `; + }) + .join("")}
      `); - return acc; - }, []); - return status.join(" "); + return acc; + }, []); + return status.join(" "); } document.addEventListener("DOMContentLoaded", () => { - const promises = []; - for (const [path, mode] of window.config.loadPathsAndModes) { - promises.push( - fetchData(path) - .then((response) => response.json()) - .then((data) => initialize(data, mode)) - ); - } - Promise.all(promises).then(() => generateResults()); + const promises = []; + for (const [path, mode] of window.config.loadPathsAndModes) { + promises.push( + fetchData(path) + .then(response => response.json()) + .then(data => initialize(data, mode)) + ); + } + Promise.all(promises).then(() => generateResults()); }); diff --git a/test262/test-config.js b/test262/test-config.js index 2ce0553..9f9f5e8 100644 --- a/test262/test-config.js +++ b/test262/test-config.js @@ -1,49 +1,39 @@ const style = getComputedStyle(document.body); const TestResult = { - PASSED: "passed", - FAILED: "failed", - SKIPPED: "skipped", - METADATA_ERROR: "metadata_error", - HARNESS_ERROR: "harness_error", - TIMEOUT_ERROR: "timeout_error", - PROCESS_ERROR: "process_error", - RUNNER_EXCEPTION: "runner_exception", - TODO_ERROR: "todo_error", - DURATION: "duration", + PASSED: "passed", + FAILED: "failed", + SKIPPED: "skipped", + METADATA_ERROR: "metadata_error", + HARNESS_ERROR: "harness_error", + TIMEOUT_ERROR: "timeout_error", + PROCESS_ERROR: "process_error", + RUNNER_EXCEPTION: "runner_exception", + TODO_ERROR: "todo_error", + DURATION: "duration", }; const TestResultColors = { - [TestResult.PASSED]: style.getPropertyValue("--color-chart-passed"), - [TestResult.FAILED]: style.getPropertyValue("--color-chart-failed"), - [TestResult.SKIPPED]: style.getPropertyValue("--color-chart-skipped"), - [TestResult.METADATA_ERROR]: style.getPropertyValue( - "--color-chart-metadata-error" - ), - [TestResult.HARNESS_ERROR]: style.getPropertyValue( - "--color-chart-harness-error" - ), - [TestResult.TIMEOUT_ERROR]: style.getPropertyValue( - "--color-chart-timeout-error" - ), - [TestResult.PROCESS_ERROR]: style.getPropertyValue( - "--color-chart-process-error" - ), - [TestResult.RUNNER_EXCEPTION]: style.getPropertyValue( - "--color-chart-runner-exception" - ), - [TestResult.TODO_ERROR]: style.getPropertyValue("--color-chart-todo-error"), + [TestResult.PASSED]: style.getPropertyValue("--color-chart-passed"), + [TestResult.FAILED]: style.getPropertyValue("--color-chart-failed"), + [TestResult.SKIPPED]: style.getPropertyValue("--color-chart-skipped"), + [TestResult.METADATA_ERROR]: style.getPropertyValue("--color-chart-metadata-error"), + [TestResult.HARNESS_ERROR]: style.getPropertyValue("--color-chart-harness-error"), + [TestResult.TIMEOUT_ERROR]: style.getPropertyValue("--color-chart-timeout-error"), + [TestResult.PROCESS_ERROR]: style.getPropertyValue("--color-chart-process-error"), + [TestResult.RUNNER_EXCEPTION]: style.getPropertyValue("--color-chart-runner-exception"), + [TestResult.TODO_ERROR]: style.getPropertyValue("--color-chart-todo-error"), }; const TestResultLabels = { - [TestResult.PASSED]: "Passed", - [TestResult.FAILED]: "Failed", - [TestResult.SKIPPED]: "Skipped", - [TestResult.METADATA_ERROR]: "Metadata failed to parse", - [TestResult.HARNESS_ERROR]: "Harness file failed to parse or run", - [TestResult.TIMEOUT_ERROR]: "Timed out", - [TestResult.PROCESS_ERROR]: "Crashed", - [TestResult.RUNNER_EXCEPTION]: "Unhandled runner exception", - [TestResult.TODO_ERROR]: "Not yet implemented", - [TestResult.DURATION]: "Duration (seconds)", + [TestResult.PASSED]: "Passed", + [TestResult.FAILED]: "Failed", + [TestResult.SKIPPED]: "Skipped", + [TestResult.METADATA_ERROR]: "Metadata failed to parse", + [TestResult.HARNESS_ERROR]: "Harness file failed to parse or run", + [TestResult.TIMEOUT_ERROR]: "Timed out", + [TestResult.PROCESS_ERROR]: "Crashed", + [TestResult.RUNNER_EXCEPTION]: "Unhandled runner exception", + [TestResult.TODO_ERROR]: "Not yet implemented", + [TestResult.DURATION]: "Duration (seconds)", }; diff --git a/wasm/index.html b/wasm/index.html index ba91952..d64b611 100644 --- a/wasm/index.html +++ b/wasm/index.html @@ -1,147 +1,142 @@ - + - - - - LibWasm Spec Test results - - - - - - -
      -

      LibWasm Spec test results

      -
      -

      Introduction

      -

      - These are the results of the - SerenityOS - WebAssembly library, LibWasm, running the WebAssembly - testsuite. All tests are re-run and the results updated automatically for - every push to the master branch of the repository on GitHub. Dates and - times are shown in your browser's timezone. -

      -

      - If you have any questions or want to help out with improving these - test scores, feel free to get in touch on the - SerenityOS Discord server. -

      -
      -
      -

      Per-file results

      -

      - Click here! -

      -
      -
      -

      Source code & Data

      -

      Source code:

      - -

      Data (JSON):

      - -
      -
      -

      Results

      -

      Loading...

      -
      - -
      -
      -
      -

      Performance

      -
      - -
      -
      -
      -

      Performance per test

      -
      - -
      -
      -
      - - - - - - - - - - - + & + linusg. + + + + + + + + + + + diff --git a/wasm/main.js b/wasm/main.js index f461b1c..6baa704 100644 --- a/wasm/main.js +++ b/wasm/main.js @@ -1,337 +1,326 @@ "use strict"; (() => { - const { DateTime, Duration } = luxon; + const { DateTime, Duration } = luxon; - const backgroundColor = style.getPropertyValue("--color-background"); - const textColor = style.getPropertyValue("--color-text"); - const chartBorderColor = style.getPropertyValue("--color-chart-border"); - const fontFamily = style.getPropertyValue("font-family"); - const fontSize = parseInt( - style.getPropertyValue("font-size").slice(0, -2), - 10 - ); + const backgroundColor = style.getPropertyValue("--color-background"); + const textColor = style.getPropertyValue("--color-text"); + const chartBorderColor = style.getPropertyValue("--color-chart-border"); + const fontFamily = style.getPropertyValue("font-family"); + const fontSize = parseInt(style.getPropertyValue("font-size").slice(0, -2), 10); - Chart.defaults.borderColor = textColor; - Chart.defaults.color = textColor; - Chart.defaults.font.family = fontFamily; - Chart.defaults.font.size = fontSize; + Chart.defaults.borderColor = textColor; + Chart.defaults.color = textColor; + Chart.defaults.font.family = fontFamily; + Chart.defaults.font.size = fontSize; - // place tooltip's origin point under the cursor - const tooltipPlugin = Chart.registry.getPlugin("tooltip"); - tooltipPlugin.positioners.underCursor = function (elements, eventPosition) { - const pos = tooltipPlugin.positioners.average(elements); + // place tooltip's origin point under the cursor + const tooltipPlugin = Chart.registry.getPlugin("tooltip"); + tooltipPlugin.positioners.underCursor = function (elements, eventPosition) { + const pos = tooltipPlugin.positioners.average(elements); - if (pos === false) { - return false; - } + if (pos === false) { + return false; + } - return { - x: pos.x, - y: eventPosition.y, + return { + x: pos.x, + y: eventPosition.y, + }; }; - }; - class LineWithVerticalHoverLineController extends Chart.LineController { - draw() { - super.draw(arguments); + class LineWithVerticalHoverLineController extends Chart.LineController { + draw() { + super.draw(arguments); - if (!this.chart.tooltip._active.length) return; + if (!this.chart.tooltip._active.length) return; - const { x } = this.chart.tooltip._active[0].element; - const { top: topY, bottom: bottomY } = this.chart.chartArea; - const ctx = this.chart.ctx; + const { x } = this.chart.tooltip._active[0].element; + const { top: topY, bottom: bottomY } = this.chart.chartArea; + const ctx = this.chart.ctx; - ctx.save(); - ctx.beginPath(); - ctx.moveTo(x, topY); - ctx.lineTo(x, bottomY); - ctx.lineWidth = 1; - ctx.strokeStyle = chartBorderColor; - ctx.stroke(); - ctx.restore(); + ctx.save(); + ctx.beginPath(); + ctx.moveTo(x, topY); + ctx.lineTo(x, bottomY); + ctx.lineWidth = 1; + ctx.strokeStyle = chartBorderColor; + ctx.stroke(); + ctx.restore(); + } } - } - LineWithVerticalHoverLineController.id = "lineWithVerticalHoverLine"; - LineWithVerticalHoverLineController.defaults = Chart.LineController.defaults; - Chart.register(LineWithVerticalHoverLineController); + LineWithVerticalHoverLineController.id = "lineWithVerticalHoverLine"; + LineWithVerticalHoverLineController.defaults = Chart.LineController.defaults; + Chart.register(LineWithVerticalHoverLineController); - // This is when we started running the tests on Idan's self-hosted runner. Before that, - // durations varied a lot across runs. See https://github.com/SerenityOS/serenity/pull/7718. - const PERFORMANCE_CHART_START_DATE_TIME = DateTime.fromISO("2021-07-04"); + // This is when we started running the tests on Idan's self-hosted runner. Before that, + // durations varied a lot across runs. See https://github.com/SerenityOS/serenity/pull/7718. + const PERFORMANCE_CHART_START_DATE_TIME = DateTime.fromISO("2021-07-04"); - function prepareDataForCharts(data) { - const charts = { - [""]: { - data: { - [TestResult.PASSED]: [], - [TestResult.FAILED]: [], - [TestResult.SKIPPED]: [], - [TestResult.METADATA_ERROR]: [], - [TestResult.HARNESS_ERROR]: [], - [TestResult.TIMEOUT_ERROR]: [], - [TestResult.PROCESS_ERROR]: [], - [TestResult.RUNNER_EXCEPTION]: [], - [TestResult.TODO_ERROR]: [], - [TestResult.DURATION]: [], - }, - datasets: [], - metadata: [], - }, - ["performance"]: { - data: { - [TestResult.DURATION]: [], - }, - datasets: [], - metadata: [], - }, - ["performance-per-test"]: { - data: { - [TestResult.DURATION]: [], - }, - datasets: [], - metadata: [], - }, - }; + function prepareDataForCharts(data) { + const charts = { + [""]: { + data: { + [TestResult.PASSED]: [], + [TestResult.FAILED]: [], + [TestResult.SKIPPED]: [], + [TestResult.METADATA_ERROR]: [], + [TestResult.HARNESS_ERROR]: [], + [TestResult.TIMEOUT_ERROR]: [], + [TestResult.PROCESS_ERROR]: [], + [TestResult.RUNNER_EXCEPTION]: [], + [TestResult.TODO_ERROR]: [], + [TestResult.DURATION]: [], + }, + datasets: [], + metadata: [], + }, + ["performance"]: { + data: { + [TestResult.DURATION]: [], + }, + datasets: [], + metadata: [], + }, + ["performance-per-test"]: { + data: { + [TestResult.DURATION]: [], + }, + datasets: [], + metadata: [], + }, + }; - console.log(data); - for (const entry of data) { - const test = entry.tests["spectest"]; - const results = test.results; - charts[""].metadata.push({ - commitTimestamp: entry.commit_timestamp, - runTimestamp: entry.run_timestamp, - duration: test.duration, - versions: entry.versions, - total: results.total, - }); - for (const testResult in charts[""].data) { - if (testResult === TestResult.DURATION) { - continue; - } - charts[""].data[testResult].push({ - x: entry.commit_timestamp * 1000, - y: results[testResult] || 0, - }); - } + console.log(data); + for (const entry of data) { + const test = entry.tests["spectest"]; + const results = test.results; + charts[""].metadata.push({ + commitTimestamp: entry.commit_timestamp, + runTimestamp: entry.run_timestamp, + duration: test.duration, + versions: entry.versions, + total: results.total, + }); + for (const testResult in charts[""].data) { + if (testResult === TestResult.DURATION) { + continue; + } + charts[""].data[testResult].push({ + x: entry.commit_timestamp * 1000, + y: results[testResult] || 0, + }); + } - const dt = DateTime.fromSeconds(entry.commit_timestamp); - if (dt < PERFORMANCE_CHART_START_DATE_TIME) { - continue; - } + const dt = DateTime.fromSeconds(entry.commit_timestamp); + if (dt < PERFORMANCE_CHART_START_DATE_TIME) { + continue; + } - // chart-performance - const performanceTests = test; - const performanceChart = charts["performance"]; - const performanceResults = performanceTests?.results; - if (performanceResults) { - performanceChart.metadata.push({ - commitTimestamp: entry.commit_timestamp, - runTimestamp: entry.run_timestamp, - duration: performanceTests.duration, - versions: entry.versions, - total: performanceResults.total, - }); - performanceChart.data["duration"].push({ - x: entry.commit_timestamp * 1000, - y: performanceTests.duration, - }); - } + // chart-performance + const performanceTests = test; + const performanceChart = charts["performance"]; + const performanceResults = performanceTests?.results; + if (performanceResults) { + performanceChart.metadata.push({ + commitTimestamp: entry.commit_timestamp, + runTimestamp: entry.run_timestamp, + duration: performanceTests.duration, + versions: entry.versions, + total: performanceResults.total, + }); + performanceChart.data["duration"].push({ + x: entry.commit_timestamp * 1000, + y: performanceTests.duration, + }); + } - // chart-performance-per-test - const performancePerTestTests = test; - const performancePerTestChart = charts["performance-per-test"]; - const performancePerTestResults = performancePerTestTests?.results; - if (performancePerTestResults) { - performancePerTestChart.metadata.push({ - commitTimestamp: entry.commit_timestamp, - runTimestamp: entry.run_timestamp, - duration: - performancePerTestTests.duration / performancePerTestResults.total, - versions: entry.versions, - total: performancePerTestResults.total, - }); - performancePerTestChart.data["duration"].push({ - x: entry.commit_timestamp * 1000, - y: performancePerTestTests.duration / performancePerTestResults.total, - }); - } - } + // chart-performance-per-test + const performancePerTestTests = test; + const performancePerTestChart = charts["performance-per-test"]; + const performancePerTestResults = performancePerTestTests?.results; + if (performancePerTestResults) { + performancePerTestChart.metadata.push({ + commitTimestamp: entry.commit_timestamp, + runTimestamp: entry.run_timestamp, + duration: performancePerTestTests.duration / performancePerTestResults.total, + versions: entry.versions, + total: performancePerTestResults.total, + }); + performancePerTestChart.data["duration"].push({ + x: entry.commit_timestamp * 1000, + y: performancePerTestTests.duration / performancePerTestResults.total, + }); + } + } - for (const chart in charts) { - for (const testResult in charts[chart].data) { - charts[chart].datasets.push({ - label: TestResultLabels[testResult], - data: charts[chart].data[testResult], - backgroundColor: TestResultColors[testResult], - borderWidth: 2, - borderColor: chartBorderColor, - pointRadius: 0, - pointHoverRadius: 0, - fill: true, - }); - } - delete charts[chart].data; - } + for (const chart in charts) { + for (const testResult in charts[chart].data) { + charts[chart].datasets.push({ + label: TestResultLabels[testResult], + data: charts[chart].data[testResult], + backgroundColor: TestResultColors[testResult], + borderWidth: 2, + borderColor: chartBorderColor, + pointRadius: 0, + pointHoverRadius: 0, + fill: true, + }); + } + delete charts[chart].data; + } - return { charts }; - } + return { charts }; + } - function initializeChart( - element, - { datasets, metadata }, - { xAxisTitle = "Time", yAxisTitle = "Number of tests" } = {} - ) { - const ctx = element.getContext("2d"); + function initializeChart( + element, + { datasets, metadata }, + { xAxisTitle = "Time", yAxisTitle = "Number of tests" } = {} + ) { + const ctx = element.getContext("2d"); - new Chart(ctx, { - type: "lineWithVerticalHoverLine", - data: { - datasets, - }, - options: { - parsing: false, - normalized: true, - responsive: true, - maintainAspectRatio: false, - animation: false, - plugins: { - zoom: { - zoom: { - mode: "x", - wheel: { - enabled: true, - }, - }, - pan: { - enabled: true, - mode: "x", + new Chart(ctx, { + type: "lineWithVerticalHoverLine", + data: { + datasets, }, - }, - hover: { - mode: "index", - intersect: false, - }, - tooltip: { - mode: "index", - intersect: false, - usePointStyle: true, - boxWidth: 12, - boxHeight: 12, - padding: 20, - position: "underCursor", - titleColor: textColor, - bodyColor: textColor, - footerColor: textColor, - footerFont: { weight: "normal" }, - footerMarginTop: 20, - backgroundColor: backgroundColor, - callbacks: { - title: () => { - return null; - }, - beforeBody: (context) => { - const { dataIndex } = context[0]; - const { total } = metadata[dataIndex]; - const formattedValue = total.toLocaleString("en-US"); - // Leading spaces to make up for missing color circle - return ` Number of tests: ${formattedValue}`; - }, - label: (context) => { - // Space as padding between color circle and label - const formattedValue = context.parsed.y.toLocaleString("en-US"); - if ( - context.dataset.label !== - TestResultLabels[TestResult.DURATION] - ) { - const { total } = metadata[context.dataIndex]; - const percentOfTotal = ( - (context.parsed.y / total) * - 100 - ).toFixed(2); - return ` ${context.dataset.label}: ${formattedValue} (${percentOfTotal}%)`; - } else { - return ` ${context.dataset.label}: ${formattedValue}`; - } - }, + options: { + parsing: false, + normalized: true, + responsive: true, + maintainAspectRatio: false, + animation: false, + plugins: { + zoom: { + zoom: { + mode: "x", + wheel: { + enabled: true, + }, + }, + pan: { + enabled: true, + mode: "x", + }, + }, + hover: { + mode: "index", + intersect: false, + }, + tooltip: { + mode: "index", + intersect: false, + usePointStyle: true, + boxWidth: 12, + boxHeight: 12, + padding: 20, + position: "underCursor", + titleColor: textColor, + bodyColor: textColor, + footerColor: textColor, + footerFont: { weight: "normal" }, + footerMarginTop: 20, + backgroundColor: backgroundColor, + callbacks: { + title: () => { + return null; + }, + beforeBody: context => { + const { dataIndex } = context[0]; + const { total } = metadata[dataIndex]; + const formattedValue = total.toLocaleString("en-US"); + // Leading spaces to make up for missing color circle + return ` Number of tests: ${formattedValue}`; + }, + label: context => { + // Space as padding between color circle and label + const formattedValue = context.parsed.y.toLocaleString("en-US"); + if ( + context.dataset.label !== TestResultLabels[TestResult.DURATION] + ) { + const { total } = metadata[context.dataIndex]; + const percentOfTotal = ( + (context.parsed.y / total) * + 100 + ).toFixed(2); + return ` ${context.dataset.label}: ${formattedValue} (${percentOfTotal}%)`; + } else { + return ` ${context.dataset.label}: ${formattedValue}`; + } + }, - footer: (context) => { - const { dataIndex } = context[0]; - const { - commitTimestamp, - duration: durationSeconds, - versions, - } = metadata[dataIndex]; - const dateTime = DateTime.fromSeconds(commitTimestamp); - const duration = Duration.fromMillis(durationSeconds * 1000); - const serenityVersion = versions.serenity.substring(0, 7); - return `\ + footer: context => { + const { dataIndex } = context[0]; + const { + commitTimestamp, + duration: durationSeconds, + versions, + } = metadata[dataIndex]; + const dateTime = DateTime.fromSeconds(commitTimestamp); + const duration = Duration.fromMillis(durationSeconds * 1000); + const serenityVersion = versions.serenity.substring(0, 7); + return `\ Committed on ${dateTime.toLocaleString(DateTime.DATETIME_SHORT)}, \ run took ${duration.toISOTime()} Versions: serenity@${serenityVersion}`; - }, - }, - }, - legend: { - align: "end", - labels: { - usePointStyle: true, - boxWidth: 10, - // Only include passed, failed, TODO, and crashed in the legend - filter: ({ text }) => - text === TestResultLabels[TestResult.PASSED] || - text === TestResultLabels[TestResult.FAILED] || - text === TestResultLabels[TestResult.TODO_ERROR] || - text === TestResultLabels[TestResult.PROCESS_ERROR], - }, - }, - }, - scales: { - x: { - type: "time", - title: { - display: true, - text: xAxisTitle, - }, - grid: { - borderColor: textColor, - color: "transparent", - borderWidth: 2, - }, - }, - y: { - stacked: true, - beginAtZero: true, - title: { - display: true, - text: yAxisTitle, - }, - grid: { - borderColor: textColor, - color: chartBorderColor, - borderWidth: 2, + }, + }, + }, + legend: { + align: "end", + labels: { + usePointStyle: true, + boxWidth: 10, + // Only include passed, failed, TODO, and crashed in the legend + filter: ({ text }) => + text === TestResultLabels[TestResult.PASSED] || + text === TestResultLabels[TestResult.FAILED] || + text === TestResultLabels[TestResult.TODO_ERROR] || + text === TestResultLabels[TestResult.PROCESS_ERROR], + }, + }, + }, + scales: { + x: { + type: "time", + title: { + display: true, + text: xAxisTitle, + }, + grid: { + borderColor: textColor, + color: "transparent", + borderWidth: 2, + }, + }, + y: { + stacked: true, + beginAtZero: true, + title: { + display: true, + text: yAxisTitle, + }, + grid: { + borderColor: textColor, + color: chartBorderColor, + borderWidth: 2, + }, + }, + }, }, - }, - }, - }, - }); - } + }); + } - function initializeSummary( - element, - runTimestamp, - commitHash, - durationSeconds, - results - ) { - const dateTime = DateTime.fromSeconds(runTimestamp); - const duration = Duration.fromMillis(durationSeconds * 1000); - const passed = results[TestResult.PASSED]; - const total = results.total; - const percent = ((passed / total) * 100).toFixed(2); - element.innerHTML = ` + function initializeSummary(element, runTimestamp, commitHash, durationSeconds, results) { + const dateTime = DateTime.fromSeconds(runTimestamp); + const duration = Duration.fromMillis(durationSeconds * 1000); + const passed = results[TestResult.PASSED]; + const total = results.total; + const percent = ((passed / total) * 100).toFixed(2); + element.innerHTML = ` The last test run was on ${dateTime.toLocaleString(DateTime.DATETIME_SHORT)} for commit @@ -348,46 +337,44 @@ Versions: serenity@${serenityVersion}`; and took ${duration.toISOTime()}. ${passed} of ${total} tests passed, i.e. ${percent}%. `; - } - - function initialize(data) { - const { charts } = prepareDataForCharts(data); - initializeChart(document.getElementById("chart"), charts[""]); - initializeChart( - document.getElementById("chart-performance"), - charts["performance"], - { yAxisTitle: TestResultLabels[TestResult.DURATION] } - ); - initializeChart( - document.getElementById("chart-performance-per-test"), - charts["performance-per-test"], - { yAxisTitle: TestResultLabels[TestResult.DURATION] } - ); - const last = data.slice(-1)[0]; - if (last) { - initializeSummary( - document.getElementById("summary"), - last.run_timestamp, - last.versions.serenity, - last.tests["spectest"].duration, - last.tests["spectest"].results - ); } - } - document.addEventListener("DOMContentLoaded", () => { - fetchData("wasm/results.json") - .then((response) => response.json()) - .then((data) => { - data.sort((a, b) => - a.commit_timestamp === b.commit_timestamp - ? 0 - : a.commit_timestamp < b.commit_timestamp - ? -1 - : 1 + function initialize(data) { + const { charts } = prepareDataForCharts(data); + initializeChart(document.getElementById("chart"), charts[""]); + initializeChart(document.getElementById("chart-performance"), charts["performance"], { + yAxisTitle: TestResultLabels[TestResult.DURATION], + }); + initializeChart( + document.getElementById("chart-performance-per-test"), + charts["performance-per-test"], + { yAxisTitle: TestResultLabels[TestResult.DURATION] } ); - return data; - }) - .then((data) => initialize(data)); - }); + const last = data.slice(-1)[0]; + if (last) { + initializeSummary( + document.getElementById("summary"), + last.run_timestamp, + last.versions.serenity, + last.tests["spectest"].duration, + last.tests["spectest"].results + ); + } + } + + document.addEventListener("DOMContentLoaded", () => { + fetchData("wasm/results.json") + .then(response => response.json()) + .then(data => { + data.sort((a, b) => + a.commit_timestamp === b.commit_timestamp + ? 0 + : a.commit_timestamp < b.commit_timestamp + ? -1 + : 1 + ); + return data; + }) + .then(data => initialize(data)); + }); })(); diff --git a/wasm/per-file/index.html b/wasm/per-file/index.html index 7ad561a..ff4adfc 100644 --- a/wasm/per-file/index.html +++ b/wasm/per-file/index.html @@ -1,112 +1,94 @@ - + - - - - LibWasm spec test per-file results - - - - - - + + + + LibWasm spec test per-file results + + + + + + - -
      -
      - - -

      Per-file results

      -
      - Loading... -
      - -
      -
      -
      -
        -
        - - - - - - + +
        +
        + + +

        Per-file results

        +
        + Loading... +
        + +
        +
        +
        +
          +
          + + + + + + - - - + + +