;;; spine-index-model-test.el — ERT tests for spine-index-model with shelf grouping (require 'ert) (require 'cl-lib) (setq spine-skip-server-start t) (setq spine-org-file (expand-file-name "sample-books.org" (file-name-directory (directory-file-name (file-name-directory load-file-name))))) (load-file (expand-file-name "../spine.el" (file-name-directory load-file-name))) (defconst spine-index-model-test--books (spine-books) "Books fixture loaded once from sample-books.org.") (ert-deftest spine-index-model-groups-by-shelf () "Index model groups books by :shelf." (let* ((model (spine-index-model spine-index-model-test--books)) (groups (ht-get model "groups"))) (should groups) (should (= (length groups) 3)) ;; Fiction, Science Fiction, Non-Fiction (let ((labels (mapcar (lambda (g) (ht-get g "label")) groups))) (should (member "Fiction" labels)) (should (member "Science Fiction" labels)) (should (member "Non-Fiction" labels))))) (ert-deftest spine-index-model-shelf-counts () "Each shelf group has the correct number of books." (let* ((model (spine-index-model spine-index-model-test--books)) (groups (ht-get model "groups"))) (dolist (g groups) (let ((label (ht-get g "label")) (count (ht-get g "count"))) (cond ((equal label "Fiction") (should (= count 4)) (should (= (length (ht-get g "books")) 4))) ((equal label "Science Fiction") (should (= count 1)) (should (= (length (ht-get g "books")) 1))) ((equal label "Non-Fiction") (should (= count 1)) (should (= (length (ht-get g "books")) 1)))))))) (ert-deftest spine-index-model-filters-by-shelf () "filter=shelf-name shows only that shelf's books." (let* ((model (spine-index-model spine-index-model-test--books "Fiction")) (groups (ht-get model "groups"))) (should (= (length groups) 1)) (should (equal (ht-get (car groups) "label") "Fiction")))) (ert-deftest spine-index-model-includes-all-shelves-in-nav () "Shelf nav includes all shelves, including empties." (let* ((model (spine-index-model spine-index-model-test--books)) (shelf-nav (ht-get model "shelf_nav"))) (should (= (length shelf-nav) 3)) (should (member "Non-Fiction" (mapcar (lambda (n) (ht-get n "name")) shelf-nav))))) (ert-deftest spine-index-model-current-shelf () "current_shelf is set when filter is active." (let* ((model (spine-index-model spine-index-model-test--books "Science Fiction"))) (should (equal (ht-get model "current_shelf") "Science Fiction")))) (ert-deftest spine-index-model-no-current-shelf-without-filter () "current_shelf is nil when no filter." (let* ((model (spine-index-model spine-index-model-test--books))) (should-not (ht-get model "current_shelf")))) (ert-deftest spine-index-model-total-and-shelf-count () "Titlebar shows correct totals." (let* ((model (spine-index-model spine-index-model-test--books))) (should (= (ht-get model "total_books") 6)) (should (= (ht-get model "shelf_count") 3))))