Files
clojure-tui/test/tui/events_test.clj

141 lines
5.1 KiB
Clojure

(ns tui.events-test
"Unit tests for event constructors and key matching."
(:require [clojure.test :refer [deftest testing is]]
[tui.events :as ev]))
;; === Event Constructor Tests ===
(deftest quit-test
(testing "quit returns quit event"
(is (= {:type :quit} (ev/quit)))))
(deftest delayed-event-test
(testing "delayed-event creates delayed-event event"
(is (= {:type :delayed-event :ms 1000 :event {:type :tick}}
(ev/delayed-event 1000 {:type :tick}))))
(testing "delayed-event with different ms values"
(is (= 0 (:ms (ev/delayed-event 0 {:type :x}))))
(is (= 5000 (:ms (ev/delayed-event 5000 {:type :x}))))))
(deftest shell-test
(testing "shell creates shell event with vector cmd"
(is (= {:type :shell :cmd ["git" "status"] :event {:type :result}}
(ev/shell ["git" "status"] {:type :result}))))
(testing "shell preserves event data"
(let [event {:type :git-result :file "foo.txt"}]
(is (= event (:event (ev/shell ["git" "diff"] event)))))))
(deftest batch-test
(testing "batch creates batch event"
(let [e1 {:type :a}
e2 {:type :b}
result (ev/batch e1 e2)]
(is (= :batch (:type result)))
(is (= [e1 e2] (:events result)))))
(testing "batch filters nil events"
(let [result (ev/batch nil {:type :a} nil {:type :b} nil)]
(is (= [{:type :a} {:type :b}] (:events result)))))
(testing "batch returns nil for all-nil events"
(is (nil? (ev/batch nil nil nil))))
(testing "batch returns nil for no events"
(is (nil? (ev/batch)))))
(deftest sequential-test
(testing "sequential creates sequential event"
(let [e1 {:type :a}
e2 {:type :b}
result (ev/sequential e1 e2)]
(is (= :sequential (:type result)))
(is (= [e1 e2] (:events result)))))
(testing "sequential filters nil events"
(let [result (ev/sequential nil {:type :a} nil {:type :b} nil)]
(is (= [{:type :a} {:type :b}] (:events result)))))
(testing "sequential returns nil for all-nil events"
(is (nil? (ev/sequential nil nil nil))))
(testing "sequential returns nil for no events"
(is (nil? (ev/sequential)))))
(deftest debounce-test
(testing "debounce creates debounce event"
(is (= {:type :debounce :id :search :ms 300 :event {:type :search-query}}
(ev/debounce :search 300 {:type :search-query}))))
(testing "debounce with different ids"
(is (= :resize (:id (ev/debounce :resize 100 {:type :x}))))
(is (= :input (:id (ev/debounce :input 50 {:type :x}))))))
;; === Key Matching Tests ===
(deftest key=-basic-test
(testing "matches plain character"
(is (ev/key= {:type :key :key \q} \q))
(is (ev/key= {:type :key :key \a} \a))
(is (ev/key= {:type :key :key \1} \1)))
(testing "does not match different character"
(is (not (ev/key= {:type :key :key \q} \a)))
(is (not (ev/key= {:type :key :key \x} \y)))))
(deftest key=-special-keys-test
(testing "matches special keys"
(is (ev/key= {:type :key :key :enter} :enter))
(is (ev/key= {:type :key :key :escape} :escape))
(is (ev/key= {:type :key :key :up} :up))
(is (ev/key= {:type :key :key :f1} :f1)))
(testing "does not match wrong special keys"
(is (not (ev/key= {:type :key :key :up} :down)))
(is (not (ev/key= {:type :key :key :enter} :escape)))))
(deftest key=-with-modifiers-test
(testing "matches key with exact modifiers"
(is (ev/key= {:type :key :key \c :modifiers #{:ctrl}} \c #{:ctrl}))
(is (ev/key= {:type :key :key \z :modifiers #{:ctrl :shift}} \z #{:ctrl :shift}))
(is (ev/key= {:type :key :key \a :modifiers #{:shift}} \a #{:shift})))
(testing "does not match with wrong modifiers"
(is (not (ev/key= {:type :key :key \c :modifiers #{:ctrl}} \c #{:alt})))
(is (not (ev/key= {:type :key :key \c :modifiers #{:ctrl :shift}} \c #{:ctrl}))))
(testing "does not match when modifiers present but not specified"
(is (not (ev/key= {:type :key :key \c :modifiers #{:ctrl}} \c)))
(is (not (ev/key= {:type :key :key \a :modifiers #{:shift}} \a))))
(testing "does not match when modifiers specified but not present"
(is (not (ev/key= {:type :key :key \c} \c #{:ctrl})))))
(deftest key=-non-key-events-test
(testing "returns false for non-key events"
(is (not (ev/key= {:type :quit} \q)))
(is (not (ev/key= {:type :tick} :enter)))
(is (not (ev/key= nil \a)))))
;; === Composition Tests ===
(deftest composed-events-test
(testing "can compose multiple event constructors"
(let [result (ev/batch
(ev/shell ["git" "status"] {:type :status})
(ev/delayed-event 1000 {:type :refresh}))]
(is (= :batch (:type result)))
(is (= 2 (count (:events result))))
(is (= :shell (:type (first (:events result)))))
(is (= :delayed-event (:type (second (:events result)))))))
(testing "can nest batch in sequential"
(let [result (ev/sequential
{:type :start}
(ev/batch
(ev/shell ["git" "add" "."] {:type :added})
(ev/shell ["git" "status"] {:type :status})))]
(is (= :sequential (:type result)))
(is (= :batch (:type (second (:events result))))))))