This commit is contained in:
2026-02-03 12:22:19 -05:00
parent 2c103f7f96
commit 0702d27166
2 changed files with 400 additions and 405 deletions
+121 -89
View File
@@ -1,15 +1,18 @@
(ns lazygitclj.core-test
"Unit tests for lazygitclj.core namespace - model and update functions"
(:require [clojure.test :refer [deftest testing is]]
[lazygitclj.core :as core]))
[lazygitclj.core :as core]
[tui.events :as ev]))
;; Helper to create key messages in the format the TUI library uses
(defn key-msg [k]
(cond
(char? k) [:key {:char k}]
(keyword? k) [:key k]
(and (vector? k) (= :ctrl (first k))) [:key {:ctrl true :char (second k)}]
:else [:key k]))
;; Helper to create key events in the new format
(defn key-event
([k]
(cond
(char? k) {:type :key :key k}
(keyword? k) {:type :key :key k}
:else {:type :key :key k}))
([k modifiers]
{:type :key :key k :modifiers modifiers}))
;; === Model Tests ===
@@ -108,178 +111,207 @@
;; === Update Tests ===
(deftest test-update-model-quit
(testing "q returns quit command"
(let [[model cmd] (core/update-model {} (key-msg \q))]
(is (= [:quit] cmd))))
(testing "q returns quit event"
(let [{:keys [events]} (core/update-model {:model {} :event (key-event \q)})]
(is (= [{:type :quit}] events))))
(testing "ctrl-c returns quit command"
(let [[model cmd] (core/update-model {} [:key {:ctrl true :char \c}])]
(is (= [:quit] cmd)))))
(testing "ctrl-c returns quit event"
(let [{:keys [events]} (core/update-model {:model {} :event (key-event \c #{:ctrl})})]
(is (= [{:type :quit}] events)))))
(deftest test-update-model-panel-switch
(testing "number keys switch panels (2-5 matching lazygit)"
(let [[model _] (core/update-model {:panel :commits :cursor 0
:staged [] :unstaged []} (key-msg \2))]
(let [{:keys [model]} (core/update-model {:model {:panel :commits :cursor 0
:staged [] :unstaged []}
:event (key-event \2)})]
(is (= :files (:panel model))))
(let [[model _] (core/update-model {:panel :files :cursor 0
:branches-tab :local
:branches [] :remote-branches []
:tags []} (key-msg \3))]
(let [{:keys [model]} (core/update-model {:model {:panel :files :cursor 0
:branches-tab :local
:branches [] :remote-branches []
:tags []}
:event (key-event \3)})]
(is (= :branches (:panel model))))
(let [[model _] (core/update-model {:panel :files :cursor 0
:commits-tab :commits
:commits [] :reflog []} (key-msg \4))]
(let [{:keys [model]} (core/update-model {:model {:panel :files :cursor 0
:commits-tab :commits
:commits [] :reflog []}
:event (key-event \4)})]
(is (= :commits (:panel model))))
(let [[model _] (core/update-model {:panel :files :cursor 0
:stashes []} (key-msg \5))]
(let [{:keys [model]} (core/update-model {:model {:panel :files :cursor 0
:stashes []}
:event (key-event \5)})]
(is (= :stash (:panel model)))))
(testing "l key cycles panels right (files → branches → commits → stash → files)"
(let [[model _] (core/update-model {:panel :files :cursor 0
:branches-tab :local
:branches [] :remote-branches []
:tags []} (key-msg \l))]
(let [{:keys [model]} (core/update-model {:model {:panel :files :cursor 0
:branches-tab :local
:branches [] :remote-branches []
:tags []}
:event (key-event \l)})]
(is (= :branches (:panel model))))
(let [[model _] (core/update-model {:panel :branches :cursor 0
:commits-tab :commits
:commits [] :reflog []} (key-msg \l))]
(let [{:keys [model]} (core/update-model {:model {:panel :branches :cursor 0
:commits-tab :commits
:commits [] :reflog []}
:event (key-event \l)})]
(is (= :commits (:panel model))))
(let [[model _] (core/update-model {:panel :commits :cursor 0
:stashes []} (key-msg \l))]
(let [{:keys [model]} (core/update-model {:model {:panel :commits :cursor 0
:stashes []}
:event (key-event \l)})]
(is (= :stash (:panel model))))
(let [[model _] (core/update-model {:panel :stash :cursor 0
:staged [] :unstaged []} (key-msg \l))]
(let [{:keys [model]} (core/update-model {:model {:panel :stash :cursor 0
:staged [] :unstaged []}
:event (key-event \l)})]
(is (= :files (:panel model))))))
(deftest test-update-model-cursor-movement
(testing "j moves cursor down"
(let [[model _] (core/update-model {:panel :files :cursor 0
:staged [{:path "a"} {:path "b"}]
:unstaged []} (key-msg \j))]
(let [{:keys [model]} (core/update-model {:model {:panel :files :cursor 0
:staged [{:path "a"} {:path "b"}]
:unstaged []}
:event (key-event \j)})]
(is (= 1 (:cursor model)))))
(testing "k moves cursor up"
(let [[model _] (core/update-model {:panel :files :cursor 1
:staged [{:path "a"} {:path "b"}]
:unstaged []} (key-msg \k))]
(let [{:keys [model]} (core/update-model {:model {:panel :files :cursor 1
:staged [{:path "a"} {:path "b"}]
:unstaged []}
:event (key-event \k)})]
(is (= 0 (:cursor model)))))
(testing "down arrow moves cursor down"
(let [[model _] (core/update-model {:panel :files :cursor 0
:staged [{:path "a"} {:path "b"}]
:unstaged []} (key-msg :down))]
(let [{:keys [model]} (core/update-model {:model {:panel :files :cursor 0
:staged [{:path "a"} {:path "b"}]
:unstaged []}
:event (key-event :down)})]
(is (= 1 (:cursor model)))))
(testing "up arrow moves cursor up"
(let [[model _] (core/update-model {:panel :files :cursor 1
:staged [{:path "a"} {:path "b"}]
:unstaged []} (key-msg :up))]
(let [{:keys [model]} (core/update-model {:model {:panel :files :cursor 1
:staged [{:path "a"} {:path "b"}]
:unstaged []}
:event (key-event :up)})]
(is (= 0 (:cursor model))))))
(deftest test-update-model-help-menu
(testing "? opens help menu"
(let [[model _] (core/update-model {:menu-mode nil} (key-msg \?))]
(let [{:keys [model]} (core/update-model {:model {:menu-mode nil}
:event (key-event \?)})]
(is (= :help (:menu-mode model))))))
(deftest test-update-model-reset-menu
(testing "D opens reset options menu"
(let [[model _] (core/update-model {:menu-mode nil} (key-msg \D))]
(let [{:keys [model]} (core/update-model {:model {:menu-mode nil}
:event (key-event \d #{:shift})})]
(is (= :reset-options (:menu-mode model))))))
(deftest test-update-model-input-mode
(testing "c in files panel opens commit input when staged files exist"
(let [[model _] (core/update-model {:panel :files
:staged [{:path "a.txt"}]
:unstaged []} (key-msg \c))]
(let [{:keys [model]} (core/update-model {:model {:panel :files
:staged [{:path "a.txt"}]
:unstaged []}
:event (key-event \c)})]
(is (= :commit (:input-mode model)))))
(testing "c in files panel shows message when no staged files"
(let [[model _] (core/update-model {:panel :files
:staged []
:unstaged []} (key-msg \c))]
(let [{:keys [model]} (core/update-model {:model {:panel :files
:staged []
:unstaged []}
:event (key-event \c)})]
(is (= "Nothing staged to commit" (:message model))))))
(deftest test-update-input-mode
(testing "escape cancels input mode"
(let [[model _] (core/update-input-mode {:input-mode :commit
:input-buffer "test"
:input-context nil} (key-msg :escape))]
(let [{:keys [model]} (core/update-input-mode {:model {:input-mode :commit
:input-buffer "test"
:input-context nil}
:event (key-event :escape)})]
(is (nil? (:input-mode model)))
(is (= "" (:input-buffer model)))))
(testing "backspace removes last character"
(let [[model _] (core/update-input-mode {:input-mode :commit
:input-buffer "abc"
:input-context nil} (key-msg :backspace))]
(let [{:keys [model]} (core/update-input-mode {:model {:input-mode :commit
:input-buffer "abc"
:input-context nil}
:event (key-event :backspace)})]
(is (= "ab" (:input-buffer model))))))
(deftest test-update-commits-tabs
(testing "] switches to reflog tab in commits panel"
(let [[model _] (core/update-model {:panel :commits
:commits-tab :commits
:cursor 0
:commits []
:reflog []} (key-msg \]))]
(let [{:keys [model]} (core/update-model {:model {:panel :commits
:commits-tab :commits
:cursor 0
:commits []
:reflog []}
:event (key-event \])})]
(is (= :reflog (:commits-tab model)))))
(testing "[ switches to commits tab in commits panel"
(let [[model _] (core/update-model {:panel :commits
:commits-tab :reflog
:cursor 0
:commits []
:reflog []} (key-msg \[))]
(let [{:keys [model]} (core/update-model {:model {:panel :commits
:commits-tab :reflog
:cursor 0
:commits []
:reflog []}
:event (key-event \[)})]
(is (= :commits (:commits-tab model))))))
(deftest test-update-branches-tabs
(testing "] cycles branches tabs forward"
(let [[model _] (core/update-branches {:branches-tab :local
:cursor 0
:branches []} (key-msg \]))]
(let [{:keys [model]} (core/update-branches {:model {:branches-tab :local
:cursor 0
:branches []}
:event (key-event \])})]
(is (= :remotes (:branches-tab model))))
(let [[model _] (core/update-branches {:branches-tab :remotes
:cursor 0
:remote-branches []} (key-msg \]))]
(let [{:keys [model]} (core/update-branches {:model {:branches-tab :remotes
:cursor 0
:remote-branches []}
:event (key-event \])})]
(is (= :tags (:branches-tab model))))
(let [[model _] (core/update-branches {:branches-tab :tags
:cursor 0
:tags []} (key-msg \]))]
(let [{:keys [model]} (core/update-branches {:model {:branches-tab :tags
:cursor 0
:tags []}
:event (key-event \])})]
(is (= :local (:branches-tab model)))))
(testing "[ cycles branches tabs backward"
(let [[model _] (core/update-branches {:branches-tab :local
:cursor 0
:tags []} (key-msg \[))]
(let [{:keys [model]} (core/update-branches {:model {:branches-tab :local
:cursor 0
:tags []}
:event (key-event \[)})]
(is (= :tags (:branches-tab model))))))
(deftest test-update-stash-menu
(testing "escape closes stash menu"
(let [[model _] (core/update-stash-menu {:menu-mode :stash-options} (key-msg :escape))]
(let [{:keys [model]} (core/update-stash-menu {:model {:menu-mode :stash-options}
:event (key-event :escape)})]
(is (nil? (:menu-mode model))))))
(deftest test-update-reset-menu
(testing "escape closes reset menu"
(let [[model _] (core/update-reset-menu {:menu-mode :reset-options} (key-msg :escape))]
(let [{:keys [model]} (core/update-reset-menu {:model {:menu-mode :reset-options}
:event (key-event :escape)})]
(is (nil? (:menu-mode model))))))
(deftest test-update-help
(testing "escape closes help"
(let [[model _] (core/update-help {:menu-mode :help} (key-msg :escape))]
(let [{:keys [model]} (core/update-help {:model {:menu-mode :help}
:event (key-event :escape)})]
(is (nil? (:menu-mode model)))))
(testing "q closes help"
(let [[model _] (core/update-help {:menu-mode :help} (key-msg \q))]
(let [{:keys [model]} (core/update-help {:model {:menu-mode :help}
:event (key-event \q)})]
(is (nil? (:menu-mode model)))))
(testing "? closes help"
(let [[model _] (core/update-help {:menu-mode :help} (key-msg \?))]
(let [{:keys [model]} (core/update-help {:model {:menu-mode :help}
:event (key-event \?)})]
(is (nil? (:menu-mode model))))))
;; Run tests when executed directly