oficina / memoria Public

Clone
git clone https://amadan.net/oficina/memoria

Plain git — no account needed to clone.

Download

Download this file

1package memoria
2
3import (
4 "os"
5 "path/filepath"
6 "strings"
7 "testing"
8)
9
10// Every tone `tone()` can produce is one the stylesheets define.
11//
12// The template gate reads files rather than rendering them, so it cannot
13// follow `data-tone="{{.FlashKind | tone}}"` to a value. This is the other
14// end of that: one function produces every dynamic tone in the app, and
15// its whole range is checked against the same stylesheets — including the
16// default, which is the arm an unrecognised kind lands on.
17//
18// It exists because the untoned-callout bug reached every flash message in
19// the product and three tests agreed with it. A mapping nothing checks is
20// how that happens twice.
21//
22// MUTATION-TESTED 2026-09-07, each verified red then reverted:
23//
24// tone returns "danger" for the default -> red
25// tone returns "" for an unknown kind -> red
26// tone returns "good" unchanged -> red
27func TestEveryToneIsOneTheStylesheetsDefine(t *testing.T) {
28 var css string
29 for _, name := range []string{"tokens.css", "theme.css", "memoria.css"} {
30 raw, err := os.ReadFile(filepath.Join("static", name))
31 if err != nil {
32 t.Fatalf("read %s: %v", name, err)
33 }
34 css += string(raw)
35 }
36
37 // Every kind the handlers actually set, plus one nobody sets — the
38 // default arm is the one a new flash kind lands on, and it must be
39 // styled too.
40 //
41 // **Matched against the ATTRIBUTE selector**, not against the string
42 // anywhere in the file. The previous version looked for
43 // `data-tone="negative"`, which occurs in the class selector sitting
44 // beside the attribute one — so it confirmed a spelling the templates
45 // could not use. Grepping for a string is not reading a selector.
46 for _, kind := range []string{"good", "danger", "warn", "", "something-new"} {
47 got := tone(kind)
48 if got == "" {
49 t.Errorf("tone(%q) is empty: the callout renders untoned", kind)
50 continue
51 }
52 if !strings.Contains(css, `[rst-callout][rst-tone~="`+got+`"]`) {
53 t.Errorf("tone(%q) = %q, and no stylesheet selects "+
54 "[rst-callout][rst-tone~=%q]: the callout renders as the right "+
55 "box in the wrong colour, on a message the reader is meant to "+
56 "act on", kind, got, got)
57 }
58 }
59
60 // Every kind maps somewhere distinct enough to be readable: a success
61 // and a failure must not look the same, and neither may collapse into
62 // the warning. Comparing only good against danger let a mutation send
63 // "warn" to positive.
64 seen := map[string]string{}
65 for _, kind := range []string{"good", "danger", "warn"} {
66 got := tone(kind)
67 if prev, dup := seen[got]; dup {
68 t.Errorf("tone(%q) and tone(%q) both render %q; the tone stops "+
69 "carrying information", kind, prev, got)
70 }
71 seen[got] = kind
72 }
73}
74