| Read :active, and keep a field's text inside the field c131fc6 nandi 9d ago | 1 | (ns glimmer-jvui.props-check |
| 2 | "Two prop-level bugs the tag diff could not see, checked against pixels. |
| 3 | |
| 4 | A tag being handled is not the same as a tag reading the props a client |
| 5 | actually writes. Both of these rendered perfectly and said the wrong |
| 6 | thing: a checkbutton whose tick never appeared because frq writes |
| 7 | `:active` where this read `:checked`, and a field whose text ran out past |
| 8 | its own border because nothing clipped it." |
| 9 | (:require [glimmer.core :as ui] |
| 10 | [glimmer-jvui.core] |
| 11 | [jvui.sdl :as sdl] |
| 12 | [jolt.ffi :as ffi])) |
| 13 | |
| 14 | (defn- bmp [path] |
| 15 | (let [b (java.nio.file.Files/readAllBytes |
| 16 | (java.nio.file.Path/of path (into-array String []))) |
| 17 | u (fn [i] (bit-and (int (aget b i)) 255)) |
| 18 | le (fn [i] (+ (u i) (bit-shift-left (u (+ i 1)) 8) |
| 19 | (bit-shift-left (u (+ i 2)) 16) (bit-shift-left (u (+ i 3)) 24))) |
| 20 | off (le 10) w (le 18) h (le 22) stride (* 4 (quot (+ (* w 3) 3) 4))] |
| 21 | {:w w :h h :px (fn [x y] (let [i (+ off (* (- h 1 y) stride) (* 3 x))] |
| 22 | {:b (u i) :g (u (+ i 1)) :r (u (+ i 2))}))})) |
| 23 | |
| 24 | (defn- ink-in |
| 25 | "How many pixels inside [x0 y0 x1 y1] differ from the background." |
| 26 | [{:keys [px]} bg x0 y0 x1 y1] |
| 27 | (count (for [y (range y0 y1) x (range x0 x1) |
| 28 | :let [p (px x y)] |
| 29 | :when (> (+ (abs (- (:r p) (:r bg))) (abs (- (:g p) (:g bg))) |
| 30 | (abs (- (:b p) (:b bg)))) 40)] |
| 31 | 1))) |
| 32 | |
| 33 | (defn -main [& _] |
| 34 | (let [shot (str (System/getProperty "java.io.tmpdir") "/jvui-props.bmp") |
| 35 | out (atom []) ck! (fn [n ok?] (swap! out conj [n (boolean ok?)]))] |
| 36 | (ui/run (fn [] |
| 37 | [:vbox {:spacing 8} |
| Let a container fill its parent, and report "end" as the word e72d7b0 nandi 9d ago | 38 | ;; A card paints a background, so how wide it comes out is |
| 39 | ;; visible. Nested two deep because frq's tree is nested: |
| 40 | ;; every box shrink-wrapping is how its chat column ended |
| 41 | ;; up a couple of hundred points wide in a wider window. |
| 42 | [:vbox {} [:card {} [:label {:label "x"}]]] |
| Read :active, and keep a field's text inside the field c131fc6 nandi 9d ago | 43 | ;; :active, the way frq writes it — the tick must appear. |
| 44 | [:checkbutton {:label "TLS" :active true}] |
| 45 | ;; A string far wider than the field it is in. |
| 46 | [:entry {:value "nandi-test.bsky.social-and-then-some-more-text"}]]) |
| 47 | {:title "props" :width 240 :height 140 :frames 6 :shot shot}) |
| 48 | (let [img (bmp shot) |
| 49 | bg ((:px img) 2 2)] |
| 50 | ;; The tick is inside the little box at the far left of the first row. |
| 51 | (ck! "an :active checkbutton draws its tick" |
| 52 | (> (ink-in img bg 4 4 26 30) 12)) |
| 53 | ;; Nothing may be drawn to the right of the field's own border. |
| 54 | (ck! "entry text stops at the field's edge" |
| Let a container fill its parent, and report "end" as the word e72d7b0 nandi 9d ago | 55 | (zero? (ink-in img bg 232 100 240 140))) |
| 56 | ;; The card's own background, out near the right edge: a |
| 57 | ;; shrink-wrapped one would not reach. |
| 58 | (ck! "a nested container fills the width" |
| 59 | (pos? (ink-in img bg 200 4 232 40)))) |
| Read :active, and keep a field's text inside the field c131fc6 nandi 9d ago | 60 | (doseq [[n ok?] @out] (println (if ok? "- " "FAIL ") n)) |
| 61 | (let [bad (remove second @out)] |
| 62 | (println (if (seq bad) (str (count bad) " of " (count @out) " checks FAILED") |
| 63 | (str "all " (count @out) " checks passed"))) |
| 64 | (when (seq bad) (System/exit 1))))) |