aboutsummaryrefslogtreecommitdiff
path: root/tests/test-coverage-core--backend-registry.el
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test-coverage-core--backend-registry.el')
-rw-r--r--tests/test-coverage-core--backend-registry.el109
1 files changed, 109 insertions, 0 deletions
diff --git a/tests/test-coverage-core--backend-registry.el b/tests/test-coverage-core--backend-registry.el
new file mode 100644
index 00000000..ac1f6f7d
--- /dev/null
+++ b/tests/test-coverage-core--backend-registry.el
@@ -0,0 +1,109 @@
+;;; test-coverage-core--backend-registry.el --- Tests for coverage backend registry -*- lexical-binding: t; -*-
+
+;;; Commentary:
+;; Unit tests for the backend registry.
+;;
+;; A backend is a plist with at least :name, :detect, :run, and :lcov-path
+;; keys. `cj/coverage-register-backend' adds or replaces an entry.
+;; `cj/--coverage-backend-for-project' resolves which backend applies to
+;; a project root, honoring an optional override (buffer-local
+;; `cj/coverage-backend' from .dir-locals.el in real use).
+
+;;; Code:
+
+(require 'ert)
+
+(add-to-list 'load-path (expand-file-name "modules" user-emacs-directory))
+(require 'coverage-core)
+
+(defmacro test-coverage-registry-with-empty (&rest body)
+ "Run BODY with `cj/coverage-backends' rebound to an empty list."
+ (declare (indent 0))
+ `(let ((cj/coverage-backends nil))
+ ,@body))
+
+;;; Normal cases
+
+(ert-deftest test-coverage-backend-register-adds-entry ()
+ "Normal: registering a backend makes it retrievable by name."
+ (test-coverage-registry-with-empty
+ (cj/coverage-register-backend
+ '(:name elisp :detect (lambda (_) t) :run ignore :lcov-path ignore))
+ (should (= 1 (length cj/coverage-backends)))
+ (should (eq 'elisp (plist-get (car cj/coverage-backends) :name)))))
+
+(ert-deftest test-coverage-backend-register-replaces-in-place ()
+ "Normal: re-registering by name replaces the existing entry at the same position."
+ (test-coverage-registry-with-empty
+ (cj/coverage-register-backend
+ '(:name elisp :detect (lambda (_) nil) :run ignore :lcov-path ignore))
+ (cj/coverage-register-backend
+ '(:name python :detect (lambda (_) nil) :run ignore :lcov-path ignore))
+ (cj/coverage-register-backend
+ '(:name elisp :detect (lambda (_) t) :run ignore :lcov-path ignore))
+ (should (= 2 (length cj/coverage-backends)))
+ (should (eq 'elisp (plist-get (nth 0 cj/coverage-backends) :name)))
+ (should (eq 'python (plist-get (nth 1 cj/coverage-backends) :name)))
+ (should (funcall (plist-get (nth 0 cj/coverage-backends) :detect) "/tmp"))))
+
+(ert-deftest test-coverage-backend-for-project-first-detect-wins ()
+ "Normal: resolution returns the first backend whose :detect matches."
+ (test-coverage-registry-with-empty
+ (cj/coverage-register-backend
+ '(:name a :detect (lambda (_) nil) :run ignore :lcov-path ignore))
+ (cj/coverage-register-backend
+ '(:name b :detect (lambda (_) t) :run ignore :lcov-path ignore))
+ (cj/coverage-register-backend
+ '(:name c :detect (lambda (_) t) :run ignore :lcov-path ignore))
+ (let ((backend (cj/--coverage-backend-for-project "/tmp")))
+ (should (eq 'b (plist-get backend :name))))))
+
+;;; Boundary cases
+
+(ert-deftest test-coverage-backend-for-project-empty-registry ()
+ "Boundary: empty registry returns nil, not an error."
+ (test-coverage-registry-with-empty
+ (should (null (cj/--coverage-backend-for-project "/tmp")))))
+
+(ert-deftest test-coverage-backend-for-project-no-match ()
+ "Boundary: no backend's :detect matches returns nil."
+ (test-coverage-registry-with-empty
+ (cj/coverage-register-backend
+ '(:name a :detect (lambda (_) nil) :run ignore :lcov-path ignore))
+ (cj/coverage-register-backend
+ '(:name b :detect (lambda (_) nil) :run ignore :lcov-path ignore))
+ (should (null (cj/--coverage-backend-for-project "/tmp")))))
+
+(ert-deftest test-coverage-backend-for-project-override-bypasses-detect ()
+ "Boundary: OVERRIDE returns the named backend without calling :detect."
+ (test-coverage-registry-with-empty
+ (cj/coverage-register-backend
+ '(:name a :detect (lambda (_) nil) :run ignore :lcov-path ignore))
+ (cj/coverage-register-backend
+ '(:name b :detect (lambda (_) nil) :run ignore :lcov-path ignore))
+ (let ((backend (cj/--coverage-backend-for-project "/tmp" 'b)))
+ (should (eq 'b (plist-get backend :name))))))
+
+(ert-deftest test-coverage-backend-for-project-detect-receives-root ()
+ "Boundary: the :detect function is called with the project root."
+ (test-coverage-registry-with-empty
+ (let ((captured nil))
+ (cj/coverage-register-backend
+ `(:name a
+ :detect ,(lambda (root) (setq captured root) t)
+ :run ignore :lcov-path ignore))
+ (cj/--coverage-backend-for-project "/my/root")
+ (should (equal "/my/root" captured)))))
+
+;;; Error cases
+
+(ert-deftest test-coverage-backend-for-project-override-unknown-errors ()
+ "Error: OVERRIDE that names an unregistered backend signals user-error."
+ (test-coverage-registry-with-empty
+ (cj/coverage-register-backend
+ '(:name a :detect (lambda (_) t) :run ignore :lcov-path ignore))
+ (should-error (cj/--coverage-backend-for-project "/tmp" 'bogus)
+ :type 'user-error)))
+
+(provide 'test-coverage-core--backend-registry)
+;;; test-coverage-core--backend-registry.el ends here