add surveys
This commit is contained in:
parent
6ce48aae2a
commit
ba7bd5b87f
1
surveys/code_coverage/.gitignore
vendored
Normal file
1
surveys/code_coverage/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
coverage/
|
20
surveys/code_coverage/README.md
Normal file
20
surveys/code_coverage/README.md
Normal 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.
|
||||||
|
|
8
surveys/code_coverage/deno.jsonc
Normal file
8
surveys/code_coverage/deno.jsonc
Normal 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"
|
||||||
|
}
|
||||||
|
}
|
18
surveys/code_coverage/deno.lock
Normal file
18
surveys/code_coverage/deno.lock
Normal 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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
50
surveys/code_coverage/program_1.ts
Normal file
50
surveys/code_coverage/program_1.ts
Normal 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" };
|
||||||
|
}
|
||||||
|
}
|
13
surveys/code_coverage/program_1_test.ts
Normal file
13
surveys/code_coverage/program_1_test.ts
Normal 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 } },
|
||||||
|
);
|
||||||
|
});
|
45
surveys/code_coverage/program_2.ts
Normal file
45
surveys/code_coverage/program_2.ts
Normal 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;
|
||||||
|
}
|
11
surveys/code_coverage/program_2_test.ts
Normal file
11
surveys/code_coverage/program_2_test.ts
Normal 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);
|
||||||
|
});
|
BIN
surveys/code_coverage/survey.ods
Normal file
BIN
surveys/code_coverage/survey.ods
Normal file
Binary file not shown.
38
surveys/flame_graph/README.md
Normal file
38
surveys/flame_graph/README.md
Normal 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.
|
||||||
|
|
BIN
surveys/flame_graph/program_flame_graph.png
Normal file
BIN
surveys/flame_graph/program_flame_graph.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.0 KiB |
BIN
surveys/flame_graph/survey.ods
Normal file
BIN
surveys/flame_graph/survey.ods
Normal file
Binary file not shown.
14
web/example.slg
Normal file
14
web/example.slg
Normal 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;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user