(ns tui.input-test "Unit tests for input parsing and key matching." (:require [clojure.test :refer [deftest testing is]] [tui.input :as input])) ;; === New Event Format Tests === (deftest key-match-new-format-character-test (testing "matches single character keys (new format)" (is (input/key-match? {:type :key :key \q} "q")) (is (input/key-match? {:type :key :key \a} "a")) (is (input/key-match? {:type :key :key \1} "1"))) (testing "does not match different characters" (is (not (input/key-match? {:type :key :key \q} "a"))) (is (not (input/key-match? {:type :key :key \x} "y")))) (testing "does not match ctrl+char as plain char" (is (not (input/key-match? {:type :key :key \c :modifiers #{:ctrl}} "c")))) (testing "does not match alt+char as plain char" (is (not (input/key-match? {:type :key :key \x :modifiers #{:alt}} "x"))))) (deftest key-match-new-format-special-keys-test (testing "matches special keys by keyword (new format)" (is (input/key-match? {:type :key :key :enter} :enter)) (is (input/key-match? {:type :key :key :escape} :escape)) (is (input/key-match? {:type :key :key :backspace} :backspace)) (is (input/key-match? {:type :key :key :tab} :tab))) (testing "matches arrow keys" (is (input/key-match? {:type :key :key :up} :up)) (is (input/key-match? {:type :key :key :down} :down)) (is (input/key-match? {:type :key :key :left} :left)) (is (input/key-match? {:type :key :key :right} :right))) (testing "matches function keys" (is (input/key-match? {:type :key :key :f1} :f1)) (is (input/key-match? {:type :key :key :f12} :f12))) (testing "does not match wrong special keys" (is (not (input/key-match? {:type :key :key :up} :down))) (is (not (input/key-match? {:type :key :key :enter} :escape))))) (deftest key-match-new-format-ctrl-combo-test (testing "matches ctrl+char combinations (new format)" (is (input/key-match? {:type :key :key \c :modifiers #{:ctrl}} [:ctrl \c])) (is (input/key-match? {:type :key :key \x :modifiers #{:ctrl}} [:ctrl \x])) (is (input/key-match? {:type :key :key \z :modifiers #{:ctrl}} [:ctrl \z]))) (testing "does not match wrong ctrl combinations" (is (not (input/key-match? {:type :key :key \c :modifiers #{:ctrl}} [:ctrl \x]))) (is (not (input/key-match? {:type :key :key \c} [:ctrl \c]))))) (deftest key-match-new-format-alt-combo-test (testing "matches alt+char combinations (new format)" (is (input/key-match? {:type :key :key \x :modifiers #{:alt}} [:alt \x])) (is (input/key-match? {:type :key :key \a :modifiers #{:alt}} [:alt \a]))) (testing "does not match wrong alt combinations" (is (not (input/key-match? {:type :key :key \x :modifiers #{:alt}} [:alt \y]))) (is (not (input/key-match? {:type :key :key \x} [:alt \x]))))) ;; === Legacy Event Format Tests (Backward Compatibility) === (deftest key-match-legacy-character-test (testing "matches single character keys (legacy format)" (is (input/key-match? [:key {:char \q}] "q")) (is (input/key-match? [:key {:char \a}] "a")) (is (input/key-match? [:key {:char \1}] "1"))) (testing "does not match different characters" (is (not (input/key-match? [:key {:char \q}] "a"))) (is (not (input/key-match? [:key {:char \x}] "y")))) (testing "does not match ctrl+char as plain char" (is (not (input/key-match? [:key {:ctrl true :char \c}] "c")))) (testing "does not match alt+char as plain char" (is (not (input/key-match? [:key {:alt true :char \x}] "x"))))) (deftest key-match-legacy-special-keys-test (testing "matches special keys by keyword (legacy format)" (is (input/key-match? [:key :enter] :enter)) (is (input/key-match? [:key :escape] :escape)) (is (input/key-match? [:key :backspace] :backspace)) (is (input/key-match? [:key :tab] :tab))) (testing "matches arrow keys" (is (input/key-match? [:key :up] :up)) (is (input/key-match? [:key :down] :down)) (is (input/key-match? [:key :left] :left)) (is (input/key-match? [:key :right] :right))) (testing "matches function keys" (is (input/key-match? [:key :f1] :f1)) (is (input/key-match? [:key :f12] :f12))) (testing "does not match wrong special keys" (is (not (input/key-match? [:key :up] :down))) (is (not (input/key-match? [:key :enter] :escape))))) (deftest key-match-legacy-ctrl-combo-test (testing "matches ctrl+char combinations (legacy format)" (is (input/key-match? [:key {:ctrl true :char \c}] [:ctrl \c])) (is (input/key-match? [:key {:ctrl true :char \x}] [:ctrl \x])) (is (input/key-match? [:key {:ctrl true :char \z}] [:ctrl \z]))) (testing "does not match wrong ctrl combinations" (is (not (input/key-match? [:key {:ctrl true :char \c}] [:ctrl \x]))) (is (not (input/key-match? [:key {:char \c}] [:ctrl \c]))))) (deftest key-match-legacy-alt-combo-test (testing "matches alt+char combinations (legacy format)" (is (input/key-match? [:key {:alt true :char \x}] [:alt \x])) (is (input/key-match? [:key {:alt true :char \a}] [:alt \a]))) (testing "does not match wrong alt combinations" (is (not (input/key-match? [:key {:alt true :char \x}] [:alt \y]))) (is (not (input/key-match? [:key {:char \x}] [:alt \x]))))) (deftest key-match-non-key-messages-test (testing "returns false for non-key messages" (is (not (input/key-match? {:type :tick :value 123} "q"))) (is (not (input/key-match? {:type :quit} :enter))) (is (not (input/key-match? nil "a"))))) ;; === Key to String Tests === (deftest key->str-new-format-test (testing "converts special keys to strings (new format)" (is (= "enter" (input/key->str {:type :key :key :enter}))) (is (= "escape" (input/key->str {:type :key :key :escape}))) (is (= "up" (input/key->str {:type :key :key :up}))) (is (= "f1" (input/key->str {:type :key :key :f1})))) (testing "converts character keys to strings (new format)" (is (= "q" (input/key->str {:type :key :key \q}))) (is (= "a" (input/key->str {:type :key :key \a})))) (testing "converts modifier combinations to strings (new format)" (is (= "ctrl+c" (input/key->str {:type :key :key \c :modifiers #{:ctrl}}))) (is (= "alt+x" (input/key->str {:type :key :key \x :modifiers #{:alt}}))) (is (= "shift+a" (input/key->str {:type :key :key \a :modifiers #{:shift}}))))) (deftest key->str-legacy-format-test (testing "converts special keys to strings (legacy format)" (is (= "enter" (input/key->str [:key :enter]))) (is (= "escape" (input/key->str [:key :escape]))) (is (= "up" (input/key->str [:key :up]))) (is (= "f1" (input/key->str [:key :f1])))) (testing "converts character keys to strings (legacy format)" (is (= "q" (input/key->str [:key {:char \q}]))) (is (= "a" (input/key->str [:key {:char \a}])))) (testing "converts ctrl combinations to strings (legacy format)" (is (= "ctrl+c" (input/key->str [:key {:ctrl true :char \c}])))) (testing "converts alt combinations to strings (legacy format)" (is (= "alt+x" (input/key->str [:key {:alt true :char \x}]))))) (deftest key->str-non-key-messages-test (testing "returns string for non-key messages" (is (string? (input/key->str [:tick 123]))) (is (= "" (input/key->str nil)))))