;;; test-pearl-sync-wrappers.el --- Tests for sync wrappers + pagination -*- lexical-binding: t; -*- ;; Copyright (C) 2026 Craig Jennings ;; Author: Craig Jennings ;; This program is free software: you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, either version 3 of the License, or ;; (at your option) any later version. ;; This program is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with this program. If not, see . ;;; Commentary: ;; Tests for the synchronous busy-wait wrappers (teams, states, create) and ;; the completing-read-driven selectors. The HTTP boundary is stubbed; ;; `completing-read' is stubbed for the selectors. ;;; Code: (require 'test-bootstrap (expand-file-name "test-bootstrap.el")) (require 'testutil-request (expand-file-name "testutil-request.el")) (require 'cl-lib) ;;; Synchronous wrappers (ert-deftest test-pearl-get-teams-sync-returns-teams () "The sync teams wrapper returns the async result." (testutil-linear-with-response '((data (teams (nodes . (((id . "t1") (name . "Eng"))))))) (should (= 1 (length (pearl-get-teams)))))) (ert-deftest test-pearl-get-states-sync-returns-states () "The sync states wrapper returns the async result." (testutil-linear-with-response '((data (team (states (nodes . (((id . "s1") (name . "Todo")))))) )) (should (= 1 (length (pearl-get-states "team-1")))))) (ert-deftest test-pearl-create-issue-sync-returns-issue () "The sync create wrapper returns the created issue node." (testutil-linear-with-response '((data (issueCreate (success . t) (issue (id . "i1") (identifier . "ENG-1") (title . "T"))))) (should (string-equal "ENG-1" (cdr (assoc 'identifier (pearl-create-issue "T" "" "team"))))))) (ert-deftest test-pearl-sync-wrapper-times-out-without-callback () "A sync wrapper returns nil instead of hanging when no callback fires." (let ((pearl-request-timeout 0.3) (pearl-api-key "test-key")) (cl-letf (((symbol-function 'request) (lambda (&rest _) nil))) (should (null (pearl-get-teams)))))) ;;; Selectors (completing-read stubbed) (ert-deftest test-pearl-select-team-returns-chosen-team () "Selecting a team returns the matching team alist." (let ((pearl--cache-teams '(((id . "t1") (name . "Eng")) ((id . "t2") (name . "Ops"))))) (cl-letf (((symbol-function 'completing-read) (lambda (&rest _) "Ops"))) (should (string-equal "t2" (cdr (assoc 'id (pearl-select-team)))))))) (ert-deftest test-pearl-select-project-returns-chosen-project () "Selecting a project returns the matching project alist." (cl-letf (((symbol-function 'pearl-get-projects) (lambda (_tid) '(((id . "p1") (name . "Platform"))))) ((symbol-function 'completing-read) (lambda (&rest _) "Platform"))) (should (string-equal "p1" (cdr (assoc 'id (pearl-select-project "team-1"))))))) (ert-deftest test-pearl-select-project-none-returns-nil () "Choosing None returns nil." (cl-letf (((symbol-function 'pearl-get-projects) (lambda (_tid) '(((id . "p1") (name . "Platform"))))) ((symbol-function 'completing-read) (lambda (&rest _) "None"))) (should (null (pearl-select-project "team-1"))))) (provide 'test-pearl-sync-wrappers) ;;; test-pearl-sync-wrappers.el ends here