Public
HTTP (deprecated)
Val Town is a social website to write and deploy JavaScript.
Build APIs and schedule functions from your browser.
Readme

A test utility and badge to put in your val readme to show test suite status

Example:

Usage:

  1. Make a val
  2. Make a separate test suite HTTP val for the val you want to test
  3. Import describe and it utilities
  4. Write tests
  5. Add the badge to your readme, with the url parameter pointing to the test suite val's endpoint. Tests run whenever the test suite val or the badge is fetched
import { describe, it } from "https://esm.town/v/jxnblk/test"; import { assertEquals } from "jsr:@std/assert@1"; export default describe("my test suite", () => { const sum = (a, b) => a + b; it("sums it up", () => { assertEquals(sum(1, 2), 3); }) })

Badge:

[![][badge]][url] [badge]: https://jxnblk-test.web.val.run?url=YOUR_TEST_SUITE_ENDPOINT [url]: YOUR_TEST_SUITE_URL

Example

[![][badge]][url] [badge]: https://jxnblk-test.web.val.run?url=https://jxnblk-tunatestsuite.web.val.run [url]: https://www.val.town/v/jxnblk/tunaTestSuite
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/** @jsxImportSource npm:preact */
import { render } from "npm:preact-render-to-string";
export function it(name, fn) {
const ok = "✅ [OK]: ";
const fail = "❌ [FAIL]: ";
try {
fn();
console.log(ok + name);
} catch (err) {
console.log(fail + name);
console.log(" " + err);
throw new Error(err);
}
}
export function describe(name, run) {
console.log(name);
return async function(req: Request): Promise<Response> {
await run();
return Response.json({ ok: true, status: 200 });
};
}
type BadgeStatus = "ok" | "fail" | "";
type BadgeProps = {
status: BadgeStatus;
};
const colors: Record<BadgeStatus, string> = {
ok: "green",
fail: "red",
"": "gray",
};
function Badge({ status }: BadgeProps) {
const color = colors[status];
const label = status ? status.toUpperCase() : "N/A";
const rightColor = status ? "black" : "#999";
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width="96"
height="24"
viewBox="0 0 96 24"
fill="#000"
style={{
fontFamily: "'iA Writer Mono', Menlo, monospace",
fontSize: 10,
}}
>
<rect width="32" height="24" fill={color} />
<rect x="32" width="60" height="24" fill={rightColor} />
<text x="16" y="12.5" fill="white" textAnchor="middle" alignmentBaseline="middle">
{label}
</text>
<text
x="36"
y="12.5"
fill="white"
textAnchor="left"
alignmentBaseline="middle"
>
val.town
</text>
</svg>
);
}
export default async function(req: Request): Promise<Response> {
const params = new URL(req.url).searchParams;
const valURL = params.get("url");
console.log({ valURL });
let badge = <Badge status="" />;
if (valURL) {
try {
await fetch(valURL)
.then(res => res.json())
.then(res => {
console.log(res);
if (res.error) {
badge = <Badge status="fail" />;
} else {
badge = <Badge status="ok" />;
}
})
.catch(err => {
console.log(err);
badge = <Badge status="fail" />;
});
} catch (err) {
console.log(err);
badge = <Badge status="fail" />;
}
}
const svg = render(badge);
return new Response(svg, { headers: { "Content-Type": "image/svg+xml;charset=utf-8" } });
}
jxnblk-test.web.val.run
August 23, 2024