char-slop/berry

multipurpose self-modifiable agentic harness

git clone https://git.t4t.associates/char-slop/berry

Charlotte Somtest and palette cleanups: one source for the 16-color terminal palette, no change-detector testsb3a4fb7

main
3.0 KiB72 linesraw
1import { assert, assertEquals } from "@std/assert";
2import { withDom } from "@berry/util/dom.ts";
3import { TERMINAL_PALETTE } from "@berry/util/palette.ts";
4import { ansiOutput } from "./ansi-view.ts";
5
6Deno.test("coloured output appends in place and resets for replacement snapshots", async (t) => {
7  await withDom(async () => {
8    const element = document.createElement("pre");
9    const show = ansiOutput(element);
10    const colour = (value: string) => {
11      const span = document.createElement("span");
12      span.style.color = value;
13      return span.style.color;
14    };
15    await t.step("colour arrives as soon as a split escape is completed", () => {
16      assertEquals(element.hidden, true);
17      show("start\x1b[38;2;12;");
18      assertEquals(element.textContent, "start");
19      const first = element.firstChild;
20      show("start\x1b[38;2;12;34;56mred");
21      assertEquals(element.textContent, "startred");
22      assertEquals(element.firstChild, first);
23      assertEquals(
24        (element.lastElementChild as HTMLElement).style.color,
25        colour("rgb(12, 34, 56)"),
26      );
27      const red = element.lastChild!;
28      const text = red.firstChild;
29      show("start\x1b[38;2;12;34;56mredder\x1b[0mplain");
30      assertEquals(element.textContent, "startredderplain");
31      assertEquals(element.childNodes[1], red);
32      assertEquals(red.firstChild, text);
33      assertEquals(red.textContent, "redder");
34      assertEquals((element.lastElementChild as HTMLElement).style.color, "");
35    });
36    await t.step("a truncated or replaced result resets text, style and pending controls", () => {
37      show("\x1b[31mold\x1b]unfinished");
38      show("replacement");
39      assertEquals(element.textContent, "replacement");
40      assertEquals((element.firstElementChild as HTMLElement).style.color, "");
41      show("");
42      assertEquals(element.hidden, true);
43      assertEquals(element.childNodes.length, 0);
44      show("new\x1b[32mgreen");
45      assertEquals(element.textContent, "newgreen");
46      assertEquals(
47        (element.lastElementChild as HTMLElement).style.color,
48        colour(TERMINAL_PALETTE[2]),
49      );
50    });
51    await t.step("output stays literal text rather than markup", () => {
52      show('<script>alert("x")</script>\x1b[31m<a>red</a>');
53      assertEquals(element.textContent, '<script>alert("x")</script><a>red</a>');
54      assertEquals(element.querySelector("script, a"), null);
55    });
56    await t.step("large outputs bound individual text-node edits without splitting emoji", () => {
57      show("");
58      const text = "x".repeat(16383) + "😀" + "y".repeat(50000);
59      show(text);
60      assertEquals(element.textContent, text);
61      for (const span of element.children) {
62        assert(span.textContent!.length < 20000);
63        assert(!/[\ud800-\udbff]$/.test(span.textContent!));
64        assert(!/^[\udc00-\udfff]/.test(span.textContent!));
65      }
66      const first = element.firstChild;
67      show(text + "end");
68      assertEquals(element.firstChild, first);
69      assertEquals(element.textContent, text + "end");
70    });
71  });
72});