oficina / memoria Public

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

Plain git — no account needed to clone.

Download

Download this file

1package memoriatest
2
3import (
4 "amadan.net/oficina/estilo.git/base"
5 "amadan.net/oficina/estilo.git/busy"
6 "amadan.net/oficina/estilo.git/chrome"
7 estilomenu "amadan.net/oficina/estilo.git/menu"
8 "amadan.net/oficina/estilo.git/sky"
9 "bytes"
10 "os"
11 "path/filepath"
12 "testing"
13
14 "amadan.net/oficina/estilo.git/theme"
15 "amadan.net/rastrillo/rastrillo/ui"
16)
17
18// The scaffold delivered these files once; they are app-owned from
19// then on. This test pins each vendored copy byte-identical to the
20// library it came from: a reviewer runs the suite instead of reading
21// ~56KB of assets as app diff, and a framework upgrade that forgets
22// to re-copy is caught instead of drifting silently. If you edit one
23// DELIBERATELY, delete its line below — the file is yours.
24//
25// tokens.css is the only one. select.js, datetime.js and calendar.js
26// are rastrillo's too, but no page here links them, so they are not on
27// disk (TestNoUnusedRastrilloScriptsOnDisk); rastrillo.js is estilo's.
28func TestVendoredAssetsMatchTheLibrary(t *testing.T) {
29 for name, lib := range map[string][]byte{
30 "tokens.css": ui.TokensCSS(),
31 } {
32 vendored, err := os.ReadFile(filepath.Join("..", "memoria", "static", name))
33 if err != nil {
34 t.Errorf("read vendored %s: %v", name, err)
35 continue
36 }
37 if !bytes.Equal(vendored, lib) {
38 t.Errorf("static/%s differs from the library copy; re-copy it (or delete its pin if the edit was deliberate)", name)
39 }
40 }
41}
42
43// static/theme.css is Calma with Memoria's accent, from estilo (estilo
44// AGENTS.md, decisions table, row 8). This pins it to the estilo this app
45// is built against. After an estilo upgrade, re-write it with
46// `go run ./scripts/writeestilo` — never by hand.
47func TestThemeIsEstilosForMemoria(t *testing.T) {
48 want, ok := theme.ForApp("memoria")
49 if !ok {
50 t.Fatal("estilo's theme ring has no memoria")
51 }
52 got, err := os.ReadFile(filepath.Join("..", "memoria", "static", "theme.css"))
53 if err != nil {
54 t.Fatal(err)
55 }
56 if !bytes.Equal(got, want) {
57 t.Error("static/theme.css differs from estilo's theme for memoria; run go run ./scripts/writeestilo")
58 }
59}
60
61// app.go mounts Onest at a literal pattern (the route gate reads
62// literals); this keeps that literal equal to estilo's versioned prefix.
63func TestFontRouteIsEstilosPrefix(t *testing.T) {
64 src, err := os.ReadFile(filepath.Join("..", "memoria", "app.go"))
65 if err != nil {
66 t.Fatal(err)
67 }
68 if !bytes.Contains(src, []byte(`"GET `+theme.FontPrefix+`"`)) {
69 t.Errorf("app.go does not mount Onest at %s", theme.FontPrefix)
70 }
71}
72
73// rastrillo's busy rule (Paul, 2026-09-29): a submit button's label gives
74// way to a spinner for at least 650ms, the button disables, and Back
75// resets it. static/ carries it as estilo does — the shim without the old
76// rule, busy.js and busy.css — pinned here to the estilo this app builds
77// against. After an estilo upgrade: go run ./scripts/writeestilo.
78func TestBusyFilesAreEstilos(t *testing.T) {
79 for name, want := range map[string][]byte{
80 "rastrillo.js": busy.ShimJS(),
81 "busy.js": busy.JS(),
82 "busy.css": busy.CSS(),
83 } {
84 got, err := os.ReadFile(filepath.Join("..", "memoria", "static", name))
85 if err != nil {
86 t.Fatal(err)
87 }
88 if !bytes.Equal(got, want) {
89 t.Errorf("static/%s differs from estilo's; run go run ./scripts/writeestilo", name)
90 }
91 }
92}
93
94// app.go mounts the sign-in door's sky at a literal pattern, for the same
95// reason as the font: the route gate reads literals. This keeps it equal
96// to estilo's versioned prefix, so a new sky version cannot leave the
97// door linking layers nothing serves.
98func TestSkyRouteIsEstilosPrefix(t *testing.T) {
99 src, err := os.ReadFile(filepath.Join("..", "memoria", "app.go"))
100 if err != nil {
101 t.Fatal(err)
102 }
103 if !bytes.Contains(src, []byte(`"GET `+sky.Prefix+`"`)) {
104 t.Errorf("app.go does not mount the sky at %s", sky.Prefix)
105 }
106}
107
108// The sign-in door (estilo chrome's estilo-signin and friends) is styled
109// by chrome.css and sky.css, vendored into static/ so they are served
110// fingerprinted like every other stylesheet. Pinned to the estilo this
111// app builds against; after an upgrade: go run ./scripts/writeestilo.
112func TestDoorStylesAreEstilos(t *testing.T) {
113 // And the rest of the shared chrome (round 2): links (base.css), the
114 // floating panels (menu.css) and chrome.js's Escape and outside-click
115 // close.
116 for name, want := range map[string][]byte{
117 "chrome.css": chrome.CSS(),
118 "sky.css": sky.CSS(),
119 "base.css": base.CSS(),
120 "menu.css": estilomenu.CSS(),
121 "chrome.js": chrome.JS(),
122 } {
123 got, err := os.ReadFile(filepath.Join("..", "memoria", "static", name))
124 if err != nil {
125 t.Fatal(err)
126 }
127 if !bytes.Equal(got, want) {
128 t.Errorf("static/%s differs from estilo's; run go run ./scripts/writeestilo", name)
129 }
130 }
131}
132
133// rastrillo doctor --fix re-copies what the library ships and the app
134// lacks, and at 29e4491 that includes the old combined shim (with the
135// old busy rule inside) as rastrillo.js, plus select.js, datetime.js and
136// calendar.js. Memoria links none of the three, and its rastrillo.js is
137// estilo's split shim (TestBusyFilesAreEstilos): the old shim loaded
138// beside busy.js makes the two busy rules fight. After a --fix, run
139// go run ./scripts/writeestilo and delete what it added; this fails
140// until both are done.
141func TestNoUnusedRastrilloScriptsOnDisk(t *testing.T) {
142 for _, name := range []string{"select.js", "datetime.js", "calendar.js"} {
143 if _, err := os.Stat(filepath.Join("..", "memoria", "static", name)); err == nil {
144 t.Errorf("static/%s is on disk; no page links it — delete it (rastrillo doctor --fix adds it)", name)
145 }
146 }
147}
148