diff --git a/opencortex.asd b/opencortex.asd index a54e2f9..3ee340c 100644 --- a/opencortex.asd +++ b/opencortex.asd @@ -28,7 +28,7 @@ (:file "tests/boot-sequence-tests") (:file "tests/memory-tests") (:file "tests/immune-system-tests") - (:file "tests/emacs-edit-tests")) + (:file "tests/lisp-utils-tests")) :perform (test-op (o s) (uiop:symbol-call :fiveam :run! (uiop:find-symbol* :communication-protocol-suite :opencortex-tests)) (uiop:symbol-call :fiveam :run! (uiop:find-symbol* :pipeline-suite :opencortex-pipeline-tests)) @@ -36,7 +36,8 @@ (uiop:symbol-call :fiveam :run! (uiop:find-symbol* :boot-suite :opencortex-boot-tests)) (uiop:symbol-call :fiveam :run! (uiop:find-symbol* :memory-suite :opencortex-memory-tests)) (uiop:symbol-call :fiveam :run! (uiop:find-symbol* :immune-suite :opencortex-immune-system-tests)) - (uiop:symbol-call :fiveam :run! (uiop:find-symbol* :emacs-edit-suite :opencortex-emacs-edit-tests)))) + (uiop:symbol-call :fiveam :run! (uiop:find-symbol* :emacs-edit-suite :opencortex-emacs-edit-tests)) + (uiop:symbol-call :fiveam :run! (uiop:find-symbol* :lisp-utils-suite :opencortex-lisp-utils-tests))))) (defsystem :opencortex/tui :depends-on (:opencortex :croatoan :usocket :bordeaux-threads) diff --git a/tests/lisp-utils-tests.lisp b/tests/lisp-utils-tests.lisp new file mode 100644 index 0000000..e70d69f --- /dev/null +++ b/tests/lisp-utils-tests.lisp @@ -0,0 +1,107 @@ +(defpackage :opencortex-lisp-utils-tests + (:use :cl :fiveam :opencortex) + (:export #:lisp-utils-suite)) + +(in-package :opencortex-lisp-utils-tests) + +(def-suite lisp-utils-suite + :description "Tests for the Lisp Utils skill - utilities, repair, and validation.") + +(in-suite lisp-utils-suite) + +;; Character utilities +(test count-char-balanced + (is (= (count-char #\( "(+ 1 2)") 1)) + (is (= (count-char #\) "(+ 1 2)") 1))) + +(test count-char-unbalanced + (is (= (count-char #\( "(+ 1 2") 1)) + (is (= (count-char #\) "(+ 1 2") 0))) + +(test count-char-empty + (is (= (count-char #\( "") 0))) + +;; Deterministic repair +(test deterministic-repair-balanced + (is (string= (deterministic-repair "(+ 1 2)") "(+ 1 2)"))) + +(test deterministic-repair-unbalanced-open + (is (string= (deterministic-repair "(+ 1 2") "(+ 1 2)"))) + +(test deterministic-repair-unbalanced-close + (is (string= (deterministic-repair "(+ 1 2))") "(+ 1 2)))")) ;; Left as-is (can't fix) + +(test deterministic-repair-empty + (is (string= (deterministic-repair "") ""))) + +;; ID generation +(test id-generation + (let ((id1 (emacs-edit-generate-id)) + (id2 (emacs-edit-generate-id))) + (is (plusp (length id1))) + (is (not (string= id1 id2))) ;; Likely unique + (is (= 8 (length id1))))) + +(test id-format + (let ((formatted (emacs-edit-id-format "abc12345"))) + (is (search "id:" formatted)))) + +;; Structural check (from lisp-utils) +(test structural-valid + (multiple-value-bind (ok reason line col) + (opencortex::lisp-utils-check-structural "(+ 1 2)") + (is ok))) + +(test structural-unbalanced + (multiple-value-bind (ok reason line col) + (opencortex::lisp-utils-check-structural "(+ 1 2") + (is (not ok)) + (is (search "Unbalanced" reason)))) + +(test structural-mismatched + (multiple-value-bind (ok reason line col) + (opencortex::lisp-utils-check-structural "(let [x 1])") + (is (not ok)) + (is (search "Mismatched" reason)))) + +;; Syntactic check +(test syntactic-valid + (multiple-value-bind (ok reason line col) + (opencortex::lisp-utils-check-syntactic "(+ 1 2)") + (is ok))) + +(test syntactic-invalid + (multiple-value-bind (ok reason line col) + (opencortex::lisp-utils-check-syntactic "(1+ 2 #\"") + (is (not ok)))) + +;; Semantic check +(test semantic-whitelist-safe + (multiple-value-bind (ok reason line col) + (opencortex::lisp-utils-check-semantic "(+ 1 2)") + (is ok))) + +(test semantic-blocked-eval + (multiple-value-bind (ok reason line col) + (opencortex::lisp-utils-check-semantic "(eval '(+ 1 2))") + (is (not ok)))) + +(test semantic-blocked-delete + (multiple-value-bind (ok reason line col) + (opencortex::lisp-utils-check-semantic "(delete-file \"x.txt\")") + (is (not ok)))) + +;; Unified validation +(test unified-success + (let ((result (opencortex::lisp-utils-validate "(+ 1 2)" :strict t))) + (is (eq (getf result :status) :success)))) + +(test unified-structural-fail + (let ((result (opencortex::lisp-utils-validate "(+ 1 2" :strict nil))) + (is (eq (getf result :status) :error)) + (is (eq (getf result :failed) :structural)))) + +(test unified-semantic-fail + (let ((result (opencortex::lisp-utils-validate "(delete-file \"x.txt\")" :strict t))) + (is (eq (getf result :status) :error)) + (is (eq (getf result :failed) :semantic)))) \ No newline at end of file