wren/val Public Public: anyone can read this; nobody can change it.

forked from benjivers/val

workbenchthis machine
Files a9ddab6ef893cac593648df9ff6b4d2d3d14b7bc
1
/**
2
 * The watching view: what a snapshot with no seat in it turns into on screen.
3
 */
4
5
import { describe, expect, test } from "bun:test";
6
import { drawWatching, watchLines, watching, wrap } from "../static/watch.js";
7
8
const spectator = (over: Record<string, unknown> = {}) => ({
9
  t: "s",
10
  spectator: true,
11
  why: "address",
12
  phase: "live",
13
  clock: 42.4,
14
  round: 7,
15
  score: { red: 3, blue: 3 },
16
  attackers: "red",
17
  result: null,
18
  events: ["red won the round"],
19
  feed: [],
20
  ...over,
21
});
22
23
const seated = () => ({ t: "s", phase: "live", me: { id: "p1", alive: true }, players: [] });
24
25
describe("telling a seat from a watcher", () => {
26
  test("a spectator snapshot is watching, a seat's is not", () => {
27
    expect(watching(spectator())).toBe(true);
28
    expect(watching(seated())).toBe(false);
29
  });
30
31
  test("a snapshot with no `me` is watching even if nobody flagged it", () => {
32
    expect(watching({ t: "s", phase: "live" })).toBe(true);
33
    expect(watching(null)).toBe(false);
34
    expect(watching(undefined)).toBe(false);
35
  });
36
});
37
38
describe("what the watching view says", () => {
39
  test("the score, the round and the clock, from the snapshot it was given", () => {
40
    const lines = watchLines(spectator());
41
    expect(lines.score).toBe("red 3 — 3 blue");
42
    expect(lines.clock).toBe("43s");
43
    expect(lines.phase).toBe("round 7 · live · red attacking");
44
  });
45
46
  test("the reason is named: the seat is held at this address", () => {
47
    expect(watchLines(spectator()).why).toContain("address");
48
    expect(watchLines(spectator({ why: "cookie" })).why).toContain("cookie");
49
    // A snapshot that does not say still gets a sentence, not `undefined`.
50
    expect(watchLines(spectator({ why: undefined })).why).toContain("watching");
51
  });
52
53
  test("it never claims to know where anybody is", () => {
54
    const lines = watchLines(spectator());
55
    expect(lines.note).toContain("No map");
56
    expect(JSON.stringify(lines)).not.toMatch(/"x"|"y"/);
57
  });
58
59
  test("a half-built snapshot is drawn, not thrown on", () => {
60
    const lines = watchLines({ spectator: true });
61
    expect(lines.score).toBe("red 0 — 0 blue");
62
    expect(lines.clock).toBe("0s");
63
    expect(lines.phase).toContain("round 1");
64
  });
65
});
66
67
test("long sentences are broken to fit the canvas", () => {
68
  const ctx = { measureText: (text: string) => ({ width: text.length * 10 }) };
69
  const lines = wrap(ctx, "one two three four five six", 100);
70
  expect(lines.length).toBeGreaterThan(1);
71
  for (const line of lines) expect(line.length).toBeLessThanOrEqual(10);
72
  expect(lines.join(" ")).toBe("one two three four five six");
73
});
74
75
test("drawing it fills a flat panel and writes the score, and draws no world", () => {
76
  const ops: string[] = [];
77
  const ctx = new Proxy(
78
    { measureText: (text: string) => ({ width: text.length * 6 }) } as Record<string, unknown>,
79
    {
80
      get: (target, prop: string) =>
81
        prop in target
82
          ? target[prop]
83
          : (...args: unknown[]) => ops.push(`${prop}(${args.map(String).join(",")})`),
84
      set: () => true,
85
    },
86
  );
87
  drawWatching(ctx as never, spectator(), 900, 570);
88
  // One background rectangle and nothing else with an edge: no tiles, no bodies.
89
  expect(ops.filter((op) => op.startsWith("fillRect")).length).toBe(1);
90
  expect(ops.some((op) => op.startsWith("fillText(red 3 — 3 blue"))).toBe(true);
91
  expect(ops.some((op) => op.startsWith("fillText(watching"))).toBe(true);
92
});
↑↓ navigate ↵ open esc close
↑↓ navigate ↵ open esc close

Keyboard shortcuts