;; Tests for ~reactive-islands/index/demo-temperature
;;
;; Tests the reactive logic: signal creation, computed derivation,
;; button click handlers, and value propagation.

(defsuite "temperature converter"

  (deftest "initial celsius is 20"
    (let ((celsius (signal 20)))
      (assert-signal-value celsius 20)))

  (deftest "computed fahrenheit derives from celsius"
    (let ((celsius (signal 20))
          (fahrenheit (computed (fn () (+ (* (deref celsius) 1.8) 32)))))
      (assert-signal-value fahrenheit 68)
      (assert-computed-depends-on fahrenheit celsius)))

  (deftest "+5 button increments celsius by 5"
    (let ((celsius (signal 20))
          (btn (mock-element "button")))
      (mock-add-listener! btn "click"
        (fn (e) (swap! celsius (fn (c) (+ c 5)))))
      (simulate-click btn)
      (assert-signal-value celsius 25)))

  (deftest "−5 button decrements celsius by 5"
    (let ((celsius (signal 20))
          (btn (mock-element "button")))
      (mock-add-listener! btn "click"
        (fn (e) (swap! celsius (fn (c) (- c 5)))))
      (simulate-click btn)
      (assert-signal-value celsius 15)))

  (deftest "fahrenheit updates when celsius changes"
    (let ((celsius (signal 20))
          (fahrenheit (computed (fn () (+ (* (deref celsius) 1.8) 32)))))
      (assert-signal-value fahrenheit 68)
      (reset! celsius 25)
      (assert-signal-value fahrenheit 77)
      (reset! celsius 0)
      (assert-signal-value fahrenheit 32)
      (reset! celsius 100)
      (assert-signal-value fahrenheit 212)))

  (deftest "multiple clicks accumulate"
    (let ((celsius (signal 20))
          (fahrenheit (computed (fn () (+ (* (deref celsius) 1.8) 32))))
          (plus-btn (mock-element "button"))
          (minus-btn (mock-element "button")))
      (mock-add-listener! plus-btn "click"
        (fn (e) (swap! celsius (fn (c) (+ c 5)))))
      (mock-add-listener! minus-btn "click"
        (fn (e) (swap! celsius (fn (c) (- c 5)))))
      ;; +5 +5 +5
      (simulate-click plus-btn)
      (simulate-click plus-btn)
      (simulate-click plus-btn)
      (assert-signal-value celsius 35)
      (assert-signal-value fahrenheit 95)
      ;; -5
      (simulate-click minus-btn)
      (assert-signal-value celsius 30)
      (assert-signal-value fahrenheit 86)))

  (deftest "celsius signal has subscribers after computed"
    (let ((celsius (signal 20))
          (fahrenheit (computed (fn () (+ (* (deref celsius) 1.8) 32)))))
      (assert-signal-has-subscribers celsius)))

  (deftest "click events are logged on mock element"
    (let ((btn (mock-element "button")))
      (mock-add-listener! btn "click" (fn (e) nil))
      (simulate-click btn)
      (simulate-click btn)
      (assert-event-fired btn "click")
      (assert= (event-fire-count btn "click") 2 "Expected 2 click events"))))
