add surveys

This commit is contained in:
SimonFJ20 2024-11-21 16:16:30 +01:00
parent 6ce48aae2a
commit ba7bd5b87f
13 changed files with 218 additions and 0 deletions

1
surveys/code_coverage/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
coverage/

View File

@ -0,0 +1,20 @@
# Code coverage survery
## Test
```
deno task test-coverage
```
## Instructions
Write 1) a test inside `program_1_test.ts`, testing `playerFromUnknown` and 2) a test inside `program_2_test.ts`, testing `stringToInt`. The goal should be to __test as much as the code as possible__, meaning every branch and every line of code should be tested.
The tests are done, when the participant is satisfied (or the time is up). Afterward, generate a coverage report using the following command.
```sh
deno task test-coverage
```
Note down the branch and line coverage percentages of each file.

View File

@ -0,0 +1,8 @@
{
"fmt": {
"indentWidth": 4
},
"tasks": {
"test-coverage": "deno test --coverage && deno coverage coverage/ && deno coverage coverage/ --html && firefox --file coverage/html/index.html"
}
}

View File

@ -0,0 +1,18 @@
{
"version": "4",
"specifiers": {
"jsr:@std/assert@*": "1.0.8",
"jsr:@std/internal@^1.0.5": "1.0.5"
},
"jsr": {
"@std/assert@1.0.8": {
"integrity": "ebe0bd7eb488ee39686f77003992f389a06c3da1bbd8022184804852b2fa641b",
"dependencies": [
"jsr:@std/internal"
]
},
"@std/internal@1.0.5": {
"integrity": "54a546004f769c1ac9e025abd15a76b6671ddc9687e2313b67376125650dc7ba"
}
}
}

View File

@ -0,0 +1,50 @@
export type Player = {
username: string;
level: number;
};
export type Result<T> = { ok: true; value: T } | { ok: false; error: string };
export function playerFromUnknown(input: unknown): Result<Player> {
if (input === undefined) {
return { ok: false, error: "no input" };
}
if (input === null) {
return { ok: false, error: "no input" };
}
if (typeof input === "string") {
if (!/^[\d\w(:?\\\-)]+\-\d+$/.test(input)) {
return { ok: false, error: "malformed player" };
}
const splits = input.split("-");
let username = splits[0];
if (username.includes("\\-")) {
username = username.replaceAll("\\-", "-");
}
if (splits[1].startsWith("0") && splits[1].length >= 2) {
return { ok: false, error: "malformed player" };
}
const level = parseInt(splits[1]);
return { ok: true, value: { username, level } };
} else if (typeof input === "object") {
if (Object.keys(input).length < 2) {
return { ok: false, error: "malformed player" };
}
if (Object.keys(input).length > 2) {
return { ok: false, error: "too much information" };
}
if (!("username" in input && "level" in input)) {
return { ok: false, error: "malformed player" };
}
if (typeof input.username !== "string") {
return { ok: false, error: "malformed player" };
}
if (typeof input.level !== "number") {
return { ok: false, error: "malformed player" };
}
const { username, level } = input;
return { ok: true, value: { username, level } };
} else {
return { ok: false, error: "malformed player" };
}
}

View File

@ -0,0 +1,13 @@
import { assertEquals } from "jsr:@std/assert";
import { playerFromUnknown } from "./program_1.ts";
Deno.test("must work", () => {
assertEquals(
playerFromUnknown("miklz-33"),
{ ok: true, value: { username: "miklz", level: 33 } },
);
assertEquals(
playerFromUnknown({ username: "piet", level: 2 }),
{ ok: true, value: { username: "piet", level: 2 } },
);
});

View File

@ -0,0 +1,45 @@
// deno-fmt-ignore
const charVal: {[key: string]: number} = {
"0": 0, "1": 1, "2": 2, "3": 3,
"4": 4, "5": 5, "6": 6, "7": 7,
"8": 8, "9": 9, "a": 10, "b": 11,
"c": 12, "d": 13, "e": 14, "f": 15,
};
const base2Digits = ["0", "1"];
const base8Digits = [...base2Digits, "2", "3", "4", "5", "6", "7"];
const base10Digits = [...base8Digits, "8", "9"];
const base16Digits = [...base10Digits, "a", "b", "c", "d", "e", "f"];
export function stringToInt(text: string): number {
if (text.length === 0) {
return NaN;
}
if (text[0] === "0") {
if (text.length === 1) {
return 0;
} else if (text[1] == "b") {
return parseDigits(text.slice(2), 2, base2Digits);
} else if (text[1] == "x") {
return parseDigits(text.slice(2), 16, base16Digits);
} else {
return parseDigits(text.slice(1), 8, base8Digits);
}
}
return parseDigits(text, 10, base10Digits);
}
function parseDigits(
numberText: string,
base: number,
digitSet: string[],
): number {
let value = 0;
for (const ch of numberText) {
value *= base;
if (!digitSet.includes(ch)) {
return NaN;
}
value += charVal[ch];
}
return value;
}

View File

@ -0,0 +1,11 @@
import { assertEquals } from "jsr:@std/assert";
import { stringToInt } from "./program_2.ts";
Deno.test("must work", () => {
assertEquals(stringToInt("0"), 0);
assertEquals(stringToInt("10"), 10);
assertEquals(stringToInt("0b110"), 6);
assertEquals(stringToInt("071"), 57);
assertEquals(stringToInt("0xaa"), 170);
assertEquals(stringToInt("john"), NaN);
});

Binary file not shown.

View File

@ -0,0 +1,38 @@
# Flame graph survey
Look at the following code.
```rs
fn add(a, b) {
+ a b
}
let result = 0;
let i = 0;
loop {
if >= i 10 {
break;
}
result = add(result, 5);
i = + i 1;
}
```
Imagine you were to run the code.
```
slige --run program.slg
```
What percantage distribution of the total execution time is spent in `main` and in `add`? Remember that all time spent in `add` is also time spent in `main`.
Examples:
Total program | Inside `main` | Inside `add`
---|---|---
100% | 80% | 40%
100% | 90% | 10%
100% | 96% | 70%
Note down the guesses.

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

14
web/example.slg Normal file
View File

@ -0,0 +1,14 @@
fn add(a, b) {
+ a b
}
let result = 0;
let i = 0;
loop {
if >= i 10 {
break;
}
result = add(result, 5);
i = + i 1;
}