;;; spine-add-book-test.el — ERT tests for spine-add-book (require 'ert) (require 'cl-lib) (setq spine-skip-server-start t) (setq spine-org-file (expand-file-name "test-add-temp.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))) (defun spine-add-book-test--cleanup () "Remove the test Org file if it exists." (ignore-errors (delete-file spine-org-file))) (ert-deftest spine-add-book-creates-headline () "spine-add-book creates a new book under the given shelf." (spine-add-book-test--cleanup) (unwind-protect (progn (with-temp-file spine-org-file (insert "* Fiction\n\n")) (spine-add-book :title "Test Book" :author "Author Name" :shelf "Fiction") (let ((books (spine-books))) (should books) (should (= (length books) 1)) (let ((book (car books))) (should (equal (plist-get book :title) "Test Book")) (should (equal (plist-get book :author) "Author Name")) (should (equal (plist-get book :shelf) "Fiction")) (should (plist-get book :id))))) (spine-add-book-test--cleanup))) (ert-deftest spine-add-book-sets-all-fields () "spine-add-book sets all provided fields." (spine-add-book-test--cleanup) (unwind-protect (progn (with-temp-file spine-org-file (insert "* Fiction\n\n")) (spine-add-book :title "Full Test" :author "Jane Doe" :format "hardcover" :isbn "978-1234567890" :cover "covers/test.jpg" :rec_by "Friend" :rec_note "You'll love this" :date_added "2026-06-21" :initial_note "Looking forward to this" :shelf "Fiction") (let* ((books (spine-books)) (book (car books))) (should (equal (plist-get book :title) "Full Test")) (should (equal (plist-get book :author) "Jane Doe")) (should (equal (plist-get book :format) "hardcover")) (should (equal (plist-get book :isbn) "978-1234567890")) (should (equal (plist-get book :cover) "covers/test.jpg")) (should (equal (plist-get book :rec_by) "Friend")) (should (equal (plist-get book :rec_note) "You'll love this")) (should (equal (plist-get book :added) "[2026-06-21]")) (should (equal (plist-get book :notes) '(("2026-06-21" "Looking forward to this")))))) (spine-add-book-test--cleanup))) (ert-deftest spine-add-book-omits-empty-fields () "spine-add-book does not set empty/omitted fields." (spine-add-book-test--cleanup) (unwind-protect (progn (with-temp-file spine-org-file (insert "* Fiction\n\n")) (spine-add-book :title "Minimal Book" :shelf "Fiction") (let* ((books (spine-books)) (book (car books))) (should (equal (plist-get book :title) "Minimal Book")) (should (equal (plist-get book :shelf) "Fiction")) (should-not (plist-get book :author)) (should-not (plist-get book :format)) (should-not (plist-get book :isbn)) (should-not (plist-get book :tags)))) (spine-add-book-test--cleanup))) (ert-deftest spine-add-book-requires-title () "spine-add-book signals error when title is missing." (spine-add-book-test--cleanup) (unwind-protect (should-error (spine-add-book :author "No Title" :shelf "Fiction")) (spine-add-book-test--cleanup))) (ert-deftest spine-add-book-requires-shelf () "spine-add-book signals error when shelf is missing." (spine-add-book-test--cleanup) (unwind-protect (should-error (spine-add-book :title "No Shelf")) (spine-add-book-test--cleanup))) (ert-deftest spine-add-book-generates-unique-ids () "spine-add-book generates different IDs for each book." (spine-add-book-test--cleanup) (unwind-protect (progn (with-temp-file spine-org-file (insert "* Fiction\n\n")) (spine-add-book :title "Book One" :shelf "Fiction") (spine-add-book :title "Book Two" :shelf "Fiction") (let* ((books (spine-books)) (id1 (plist-get (nth 0 books) :id)) (id2 (plist-get (nth 1 books) :id))) (should (not (equal id1 id2))))) (spine-add-book-test--cleanup))) (ert-deftest spine-add-book-creates-under-correct-shelf () "spine-add-book places the book under the named shelf." (spine-add-book-test--cleanup) (unwind-protect (progn (with-temp-file spine-org-file (insert "* Fiction\n\n* Non-Fiction\n\n")) (spine-add-book :title "Sci-Fi Book" :shelf "Fiction") (spine-add-book :title "History Book" :shelf "Non-Fiction") (let ((books (spine-books))) (should (= (length books) 2)) (should (equal (plist-get (nth 0 books) :shelf) "Fiction")) (should (equal (plist-get (nth 1 books) :shelf) "Non-Fiction")))) (spine-add-book-test--cleanup)))