test view

This commit is contained in:
Theis Pieter Hollebeek 2024-12-16 15:33:12 +01:00
parent fcec80a029
commit e1416bd0e5
5 changed files with 88 additions and 33 deletions

19
examples/test_mul.slg Normal file
View File

@ -0,0 +1,19 @@
fn print(msg: string) #[builtin(Print)] {}
fn println(msg: string) { print(msg + "\n") }
fn mul(left: int, right: int) -> int {
if left == 0 or right == 0 {
0
} else {
left * right
}
}
fn main() {
if mul(10,2) == 20 {
print("test 1 passed")
}
if mul(3,2) == 6 {
print("test 2 passed")
}
}

View File

@ -1,6 +1,6 @@
{ {
"tasks": { "tasks": {
"bundle": "deno run --allow-read --allow-write --allow-env --allow-run bundle.ts" "bundle": "deno run --check --allow-read --allow-write --allow-env --allow-run bundle.ts"
}, },
"compilerOptions": { "compilerOptions": {
"checkJs": false, "checkJs": false,

View File

@ -24,14 +24,34 @@ function colorLerp(
}; };
} }
function colorToString(color: Color): string {
return `rgb(${color.r}, ${color.g}, ${color.b})`;
}
const GREEN = { r: 42, g: 121, b: 82 };
const YELLOW = {
r: 247,
g: 203,
b: 21,
};
const RED = {
r: 167,
g: 29,
b: 49,
};
export type CodeCovRender = "performance" | "test-coverage";
export function loadCodeCoverage( export function loadCodeCoverage(
text: string, text: string,
input: data.CodeCovEntry[], input: data.CodeCovEntry[],
container: HTMLPreElement,
tooltip: HTMLElement, tooltip: HTMLElement,
) { mode: CodeCovRender,
): HTMLPreElement {
const container = document.createElement("pre");
container.classList.add("code-source");
if (input.length === 0) { if (input.length === 0) {
return; return container;
} }
const entries = input.toSorted(( const entries = input.toSorted((
a: data.CodeCovEntry, a: data.CodeCovEntry,
@ -41,7 +61,7 @@ export function loadCodeCoverage(
const elements: HTMLElement[] = []; const elements: HTMLElement[] = [];
let line = 1; let line = 1;
let col = 1; let col = 1;
const maxCovers = entries.map((v) => v.covers).reduce((acc, v) => const maxPerfCovers = entries.map((v) => v.covers).reduce((acc, v) =>
acc > Math.log10(v) ? acc : Math.log10(v) acc > Math.log10(v) ? acc : Math.log10(v)
); );
for (let index = 0; index < text.length; ++index) { for (let index = 0; index < text.length; ++index) {
@ -59,23 +79,19 @@ export function loadCodeCoverage(
} }
charEntries[`${line}-${col}`] = entry; charEntries[`${line}-${col}`] = entry;
const backgroundColor = (ratio: number) => { const perfColor = (ratio: number) => {
const clr = colorLerp(ratio, { r: 42, g: 121, b: 82 }, { const clr = colorLerp(ratio, GREEN, YELLOW, RED);
r: 247, return colorToString(clr);
g: 203,
b: 21,
}, {
r: 167,
g: 29,
b: 49,
});
return `rgb(${clr.r}, ${clr.g}, ${clr.b})`;
}; };
const span = document.createElement("span"); const span = document.createElement("span");
span.style.backgroundColor = backgroundColor( span.style.backgroundColor = mode === "performance"
Math.log10(entry.covers) / maxCovers, ? perfColor(
); Math.log10(entry.covers) / maxPerfCovers,
)
: entry.covers > 0
? colorToString(GREEN)
: colorToString(RED);
span.innerText = text[index]; span.innerText = text[index];
span.dataset.covers = entry.covers.toString(); span.dataset.covers = entry.covers.toString();
elements.push(span); elements.push(span);
@ -128,4 +144,5 @@ export function loadCodeCoverage(
tooltip.style.top = `${event.clientY + 20}px`; tooltip.style.top = `${event.clientY + 20}px`;
tooltip.innerText = `Ran ${covers} time${covers !== 1 ? "s" : ""}`; tooltip.innerText = `Ran ${covers} time${covers !== 1 ? "s" : ""}`;
}); });
return container;
} }

View File

@ -1,4 +1,4 @@
import { loadCodeCoverage } from "./code_coverage.ts"; import { CodeCovRender, loadCodeCoverage } from "./code_coverage.ts";
import * as data from "./data.ts"; import * as data from "./data.ts";
import { loadFlameGraph } from "./flamegraph.ts"; import { loadFlameGraph } from "./flamegraph.ts";
@ -69,6 +69,7 @@ async function codeCoverage(view: Element, codeData: string) {
function createRadio( function createRadio(
id: string, id: string,
content: string, content: string,
checked: boolean,
): [HTMLDivElement, HTMLInputElement] { ): [HTMLDivElement, HTMLInputElement] {
const label = document.createElement("label"); const label = document.createElement("label");
label.htmlFor = id; label.htmlFor = id;
@ -78,6 +79,7 @@ async function codeCoverage(view: Element, codeData: string) {
input.name = "coverage-radio"; input.name = "coverage-radio";
input.type = "radio"; input.type = "radio";
input.hidden = true; input.hidden = true;
input.checked = checked;
const container = document.createElement("div"); const container = document.createElement("div");
container.classList.add("coverage-radio-group"); container.classList.add("coverage-radio-group");
container.append(input, label); container.append(input, label);
@ -85,29 +87,43 @@ async function codeCoverage(view: Element, codeData: string) {
} }
const [perfGroup, perfInput] = createRadio( const [perfGroup, perfInput] = createRadio(
"performance-coverage", "performance-coverage",
"Performance", "Performance view",
true,
); );
const [testGroup, testRadio] = createRadio("test-coverage", "Test"); const [testGroup, testInput] = createRadio(
"test-coverage",
"Test view",
false,
);
function load(mode: CodeCovRender, tooltip: HTMLDivElement) {
const lines = createLineElement(codeData);
const code = loadCodeCoverage(
codeData,
codeCoverageData,
tooltip,
mode,
);
innerContainer.replaceChildren(lines, code);
}
const radios = document.createElement("div"); const radios = document.createElement("div");
radios.append(perfGroup, testGroup); radios.append(perfGroup, testGroup);
radios.classList.add("coverage-radio"); radios.classList.add("coverage-radio");
const tooltip = document.createElement("div"); const tooltip = document.createElement("div");
tooltip.id = "covers-tooltip"; tooltip.id = "covers-tooltip";
tooltip.hidden = true; tooltip.hidden = true;
const code = document.createElement("pre");
code.classList.add("code-source");
loadCodeCoverage(
codeData,
codeCoverageData,
code,
tooltip,
);
const lines = createLineElement(codeData);
innerContainer.append(lines, code);
outerContainer.append(innerContainer); outerContainer.append(innerContainer);
view.replaceChildren(outerContainer, tooltip, radios); view.replaceChildren(outerContainer, tooltip, radios);
if (perfInput.checked) {
load("performance", tooltip);
} else if (testInput.checked) {
load("test-coverage", tooltip);
}
perfInput.addEventListener("input", () => load("performance", tooltip));
testInput.addEventListener("input", () => load("test-coverage", tooltip));
} }
async function main() { async function main() {

View File

@ -131,6 +131,7 @@ main #cover {
#views-nav input:checked + label { #views-nav input:checked + label {
background-color: var(--code-status); background-color: var(--code-status);
color: var(--black); color: var(--black);
font-weight: bold;
} }
#views-layout { #views-layout {
@ -176,6 +177,8 @@ main #cover {
.coverage-radio-group input:checked ~ label { .coverage-radio-group input:checked ~ label {
background-color: var(--code-status); background-color: var(--code-status);
color: var(--black);
font-weight: bold;
} }
#flame-graph { #flame-graph {