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