aboutsummaryrefslogtreecommitdiff
path: root/tests/test-coverage-core--changed-lines.el
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-06-19 09:56:20 -0400
committerCraig Jennings <c@cjennings.net>2026-06-19 09:56:20 -0400
commitac552d5cc534cda5f3726c5848ed0162ca4cfd53 (patch)
treef3000205fd24b6f2470befd0d1d3a1d22d70a60b /tests/test-coverage-core--changed-lines.el
parent10c0d574889f177b669a4f4e55a51076da991e7c (diff)
downloaddotemacs-ac552d5cc534cda5f3726c5848ed0162ca4cfd53.tar.gz
dotemacs-ac552d5cc534cda5f3726c5848ed0162ca4cfd53.zip
test: cover pure-logic gaps found by the coverage audit
I ran make coverage and worked the report function by function, separating real gaps from interactive/IO wrappers that aren't unit-test targets. These tests fill the genuine pure-logic holes: predicates, parsers, formatters, transforms, and three modules that had no test file at all. New files cover car-member (local-repository), show-kill-insert-item (show-kill-ring), the oauth2-auto plstore cache fix (auth-config), the coverage-core project-root fallback, reconcile--dirty-p, and the recurrence-frequency dispatch in calendar-sync. Extended files add the missing branches: coverage-core's merge-base and diff /dev/null handling plus the staged and branch-vs-main scopes, the detect-system-timezone symlink path, user-constants no-op and optional-failure branches, the elfeed playlist branch with HTML-entity decoding, the duplicate-line no-comment-syntax guard, and several calendar-sync edges (exception field overrides, timestamp seconds and TZID fallback, property-line position advancement, parse-ics nil and out-of-range inputs). Mocks sit at the real boundaries (plstore, url-retrieve, process-file, git) so each function's own logic runs. Dates come from relative helpers. About 65 tests added across 15 files, and the full suite stays green.
Diffstat (limited to 'tests/test-coverage-core--changed-lines.el')
-rw-r--r--tests/test-coverage-core--changed-lines.el101
1 files changed, 101 insertions, 0 deletions
diff --git a/tests/test-coverage-core--changed-lines.el b/tests/test-coverage-core--changed-lines.el
index f271fde15..0662594b4 100644
--- a/tests/test-coverage-core--changed-lines.el
+++ b/tests/test-coverage-core--changed-lines.el
@@ -227,5 +227,106 @@ Binary files a/image.png and b/image.png differ
(should-error (cj/--coverage-changed-lines 'bogus-scope)
:type 'user-error))
+;;; Boundary cases — parser, /dev/null and orphan hunks
+
+(ert-deftest test-coverage-parse-diff-dev-null-resets-current-file ()
+ "Boundary: a \"+++ /dev/null\" target resets state so a following hunk is
+not misattributed to the previous file."
+ (let* ((input (concat "diff --git a/keep.el b/keep.el\n"
+ "--- a/keep.el\n"
+ "+++ b/keep.el\n"
+ "@@ -1,0 +1,2 @@\n"
+ "+k1\n+k2\n"
+ "diff --git a/gone.el b/gone.el\n"
+ "--- a/gone.el\n"
+ "+++ /dev/null\n"
+ "@@ -1,0 +5,2 @@\n"
+ "+orphan1\n+orphan2\n"))
+ (result (cj/--coverage-parse-diff-output input))
+ (keep (gethash "keep.el" result)))
+ (should (= 1 (hash-table-count result))) ; gone.el never recorded
+ (should (= 2 (hash-table-count keep)))
+ (should (gethash 1 keep))
+ (should (gethash 2 keep))
+ (should-not (gethash 5 keep)) ; not misattributed
+ (should-not (gethash 6 keep))))
+
+(ert-deftest test-coverage-parse-diff-hunk-before-any-file-marker ()
+ "Boundary: a hunk header before any file marker is ignored, not crashed on."
+ (let* ((input (concat "@@ -1,0 +1,2 @@\n"
+ "+orphan1\n+orphan2\n"
+ "diff --git a/real.el b/real.el\n"
+ "--- a/real.el\n"
+ "+++ b/real.el\n"
+ "@@ -1,0 +1,1 @@\n"
+ "+r1\n"))
+ (result (cj/--coverage-parse-diff-output input))
+ (real (gethash "real.el" result)))
+ (should (= 1 (hash-table-count result)))
+ (should (= 1 (hash-table-count real)))
+ (should (gethash 1 real))))
+
+;;; merge-base (stubbed git invocation)
+
+(ert-deftest test-coverage-git-merge-base-returns-trimmed-sha ()
+ "Normal: a SHA with trailing newline is trimmed and returned."
+ (cl-letf (((symbol-function 'process-file)
+ (lambda (_program _infile destination _display &rest _args)
+ (with-current-buffer destination (insert "abc123\n"))
+ 0)))
+ (should (equal (cj/--coverage-git-merge-base "main") "abc123"))))
+
+(ert-deftest test-coverage-git-merge-base-empty-output-errors ()
+ "Error: empty merge-base output signals user-error (no common commit)."
+ (cl-letf (((symbol-function 'process-file)
+ (lambda (_program _infile destination _display &rest _args)
+ (with-current-buffer destination (insert ""))
+ 0)))
+ (should-error (cj/--coverage-git-merge-base "main") :type 'user-error)))
+
+(ert-deftest test-coverage-git-merge-base-whitespace-output-errors ()
+ "Error: whitespace-only output trims to empty and signals user-error."
+ (cl-letf (((symbol-function 'process-file)
+ (lambda (_program _infile destination _display &rest _args)
+ (with-current-buffer destination (insert " \n"))
+ 0)))
+ (should-error (cj/--coverage-git-merge-base "main") :type 'user-error)))
+
+;;; changed-lines — remaining scopes (stubbed git invocation)
+
+(ert-deftest test-coverage-changed-lines-staged-stubbed ()
+ "Normal: staged scope invokes git diff --cached via argv."
+ (let (seen-calls)
+ (cl-letf (((symbol-function 'process-file)
+ (lambda (program _infile destination _display &rest args)
+ (push (cons program args) seen-calls)
+ (with-current-buffer destination
+ (insert test-coverage-diff--simple-single-file))
+ 0)))
+ (let ((result (cj/--coverage-changed-lines 'staged)))
+ (should (equal (nreverse seen-calls)
+ '(("git" "diff" "--cached" "--unified=0"))))
+ (should (= 3 (hash-table-count (gethash "foo.el" result))))))))
+
+(ert-deftest test-coverage-changed-lines-branch-vs-main-stubbed ()
+ "Normal: branch-vs-main computes merge-base against main, then diffs."
+ (let (seen-calls)
+ (cl-letf (((symbol-function 'process-file)
+ (lambda (program _infile destination _display &rest args)
+ (push (cons program args) seen-calls)
+ (with-current-buffer destination
+ (insert
+ (pcase args
+ (`("merge-base" "HEAD" "main") "abc123\n")
+ (`("diff" "abc123..HEAD" "--unified=0")
+ test-coverage-diff--simple-single-file)
+ (_ ""))))
+ 0)))
+ (let ((result (cj/--coverage-changed-lines 'branch-vs-main)))
+ (should (equal (nreverse seen-calls)
+ '(("git" "merge-base" "HEAD" "main")
+ ("git" "diff" "abc123..HEAD" "--unified=0"))))
+ (should (= 3 (hash-table-count (gethash "foo.el" result))))))))
+
(provide 'test-coverage-core--changed-lines)
;;; test-coverage-core--changed-lines.el ends here