Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ test:
$(LISP) --load .qlot/setup.lisp \
--eval '(asdf:test-system "lem-tests")' \
--eval '(asdf:test-system "lem-vi-mode")' \
--eval '(asdf:test-system "lem-transient")' \
--quit

doc:
Expand Down
8 changes: 7 additions & 1 deletion extensions/transient/lem-transient.asd
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,10 @@
:components ((:file "transient")
(:file "keymap")
(:file "popup")
(:file "demo")))
(:file "demo"))
:in-order-to ((test-op (test-op "lem-transient/tests"))))

(defsystem "lem-transient/tests"
:depends-on ("lem-transient" "rove")
:components ((:file "tests/main"))
:perform (test-op (op c) (symbol-call :rove '#:run c)))
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Contractor: dynamic_symbol_call_rule

Contract: contract

AI check failed: "dynamic_symbol_call_rule"

Reason:
Added ASDF test system uses symbol-call without documenting why it is unavoidable.


💬 Reply /dismiss <reason> to dismiss this violation.

97 changes: 97 additions & 0 deletions extensions/transient/tests/main.lisp
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
(defpackage :lem/transient/tests
(:use :cl :rove :lem/transient))

(in-package :lem/transient/tests)

(defun segments->string (segments)
"flatten rendered segment lines to a plain string."
(with-output-to-string (s)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Contractor: loop_keywords_rule

Contract: contract

AI check failed: "loop_keywords_rule"

Reason:
Added loop forms use bare loop keywords instead of colon-prefixed keywords.


💬 Reply /dismiss <reason> to dismiss this violation.

(loop for line in segments
for first := t then nil
do (unless first (write-char #\newline s))
(dolist (seg line)
(write-string (car seg) s)))))

(deftest keymap-creation
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Contractor: internal_symbol_rule

Contract: contract

AI check failed: "internal_symbol_rule"

Reason:
Added code accesses multiple internal symbols via double-colon package syntax.


💬 Reply /dismiss <reason> to dismiss this violation.

(testing "lem/transient::parse-transient produces keymap with correct properties"
(let ((km (lem/transient::parse-transient
'(:description "test"
:display-style :column
(:key "a" :suffix 'lem:nop-command :description "do a")
(:key "b" :suffix 'lem:nop-command :description "do b")))))
(ok (lem/transient::keymap-show-p km))
(ok (eq :column (lem/transient::keymap-display-style km)))
(ok (string= "test" (lem:keymap-description km)))
(ok (= 2 (length (lem:keymap-prefixes km)))))))

(deftest key-binding-and-idempotency
(testing "assign-transient-key adds binding and replaces on repeat"
(let ((km (make-instance 'lem:keymap)))
(assign-transient-key km "z" '(:suffix 'lem:nop-command :description "first"))
(ok (= 1 (length (lem:keymap-prefixes km))))
(assign-transient-key km "z" '(:suffix 'lem:nop-command :description "updated"))
(ok (= 1 (length (lem:keymap-prefixes km))) "no duplicate on re-bind")
(ok (string= "updated" (lem:prefix-description (first (lem:keymap-prefixes km)))))))
(testing "multi-key sequences interpreted as an intermediate prefix chain"
(let ((km (make-instance 'lem:keymap)))
(assign-transient-key km "e a" '(:suffix 'lem:nop-command))
(let ((inter (first (lem:keymap-prefixes km))))
(ok (lem:prefix-intermediate-p inter))
(ok (typep (prefix-suffix inter) 'lem:keymap))
(ok (= 1 (length (lem:keymap-prefixes (prefix-suffix inter)))))))))

(deftest keymap-containment
(testing "lem/transient::keymap-contains-p works for nested and unrelated keymaps"
(let* ((inner (lem/transient::parse-transient '((:key "x" :suffix 'lem:nop-command))))
(outer (make-instance 'lem:keymap)))
(lem:keymap-add-child outer inner)
(ok (lem/transient::keymap-contains-p outer inner))
(ng (lem/transient::keymap-contains-p inner outer)))))

(deftest infix-values
(testing "toggle starts nil, can be flipped"
(let ((p (parse-prefix '(:key "t" :type :toggle))))
(ng (prefix-value p))
(setf (prefix-value p) t)
(ok (prefix-value p))))
(testing "choice defaults to first option, can be changed"
(let ((p (parse-prefix '(:key "c" :type :choice :choices '("alpha" "beta")))))
(ok (string= "alpha" (prefix-value p)))
(setf (prefix-value p) "beta")
(ok (string= "beta" (prefix-value p)))))
(testing "variable-synced infix reads and writes to symbol"
(let ((var (gensym "TV-")))
(set var "initial")
(let ((p (make-instance 'lem/transient::infix)))
(setf (lem/transient::infix-variable p) var)
(ok (string= "initial" (prefix-value p)))
(setf (prefix-value p) "changed")
(ok (string= "changed" (symbol-value var)))))))

(deftest prefix-lookup-by-id
(testing "find-prefix-by-id locates prefix by id, returns nil when missing"
(let ((km (lem/transient::parse-transient '((:key "a" :id :my-id :suffix 'lem:nop-command)
(:key "b" :suffix 'lem:nop-command)))))
(let ((found (find-prefix-by-id km :my-id)))
(ok found)
(ok (eq :my-id (lem/transient::prefix-id found))))
(ng (find-prefix-by-id km :missing)))))

(deftest grid-buffer-text
(let* ((km (lem/transient::parse-transient
'(:display-style :row
(:keymap
:description "nav"
(:key "h" :description "left")
(:key "j" :description "down")
(:key "k" :description "up"))
(:keymap
:description "edit"
(:key "d" :description "delete")
(:key "y" :description "yank")))))
(layout (lem/transient::generate-layout km))
(text (segments->string (lem/transient::render-layout-to-segments layout))))
(ok (string= "[nav] | [edit]
h left | d delete
j down | y yank
k up | " text))))
1 change: 1 addition & 0 deletions extensions/transient/transient.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
:prefix-active-p
:prefix-suffix
:transient-mode
:find-prefix-by-id
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Contractor: docstring_rule

Contract: contract

AI check failed: "docstring_rule"

Reason:
An added exported function is exported from the package without a docstring shown in the added code.


💬 Reply /dismiss <reason> to dismiss this violation.

))

(in-package :lem/transient)
3 changes: 2 additions & 1 deletion extensions/vi-mode/lem-vi-mode.asd
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@
(:file "registers")
(:file "kbdmacro")
(:file "jumplist")
(:file "options")))
(:file "options")
(:file "insert")))
(:file "utils"
:pathname "tests/utils"))
:perform (test-op (op c) (symbol-call :rove '#:run c)))
Loading