summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2025-11-09 15:33:17 -0600
committerCraig Jennings <c@cjennings.net>2025-11-09 15:33:17 -0600
commit7c90919de0ab52efbf3fc18072a44fdc5bca0cd7 (patch)
tree427d54de9c91c47ec6e45cf09eef21514b6ef85a
parente3fda13930b46820f2cbdf29b33d9ef3c99fea7f (diff)
feat:system: Add system utility library with executable check
Introduce a new `system-lib.el` module providing low-level system utility functions, including function `cj/executable-exists-p` to check for the availability of programs in PATH. Integrate this library in `init.el`. test(system): Add unit tests for executable check function Create comprehensive unit tests for `cj/executable-exists-p` in `system-lib.el`, ensuring coverage of normal, boundary and error scenarios.
-rw-r--r--init.el1
-rw-r--r--modules/system-lib.el20
-rw-r--r--tests/test-system-lib-executable-exists-p.el73
3 files changed, 94 insertions, 0 deletions
diff --git a/init.el b/init.el
index cc5df3ce..17d5e315 100644
--- a/init.el
+++ b/init.el
@@ -18,6 +18,7 @@
;; ---------------------------- System Configuration ---------------------------
+(require 'system-lib) ;; low-level system utility functions
(require 'config-utilities) ;; enable for extra Emacs config debug helpers
(require 'user-constants) ;; paths for files referenced in this config
(require 'host-environment) ;; convenience functions re: host environment
diff --git a/modules/system-lib.el b/modules/system-lib.el
new file mode 100644
index 00000000..8bbf8474
--- /dev/null
+++ b/modules/system-lib.el
@@ -0,0 +1,20 @@
+;;; system-lib.el --- System utility library functions -*- lexical-binding: t; -*-
+;;
+;;; Commentary:
+;; This module provides low-level system utility functions for checking
+;; the availability of external programs and system capabilities.
+;;
+;; Functions include:
+;; - Checking if external programs are available in PATH
+;;
+;;; Code:
+
+(defun cj/executable-exists-p (program)
+ "Return non-nil if PROGRAM is available in PATH.
+PROGRAM should be a string naming an executable program."
+ (and (stringp program)
+ (not (string-empty-p program))
+ (executable-find program)))
+
+(provide 'system-lib)
+;;; system-lib.el ends here
diff --git a/tests/test-system-lib-executable-exists-p.el b/tests/test-system-lib-executable-exists-p.el
new file mode 100644
index 00000000..457bb010
--- /dev/null
+++ b/tests/test-system-lib-executable-exists-p.el
@@ -0,0 +1,73 @@
+;;; test-system-lib-executable-exists-p.el --- Tests for cj/executable-exists-p -*- lexical-binding: t; -*-
+
+;;; Commentary:
+;; Unit tests for cj/executable-exists-p function from system-lib.el.
+;; Tests whether external programs are correctly detected in PATH.
+
+;;; Code:
+
+(require 'ert)
+(require 'system-lib)
+
+;;; Normal Cases
+
+(ert-deftest test-system-lib-executable-exists-p-normal-existing-program-returns-path ()
+ "Test that existing program in PATH returns non-nil.
+
+Standard case: checking for a program that definitely exists on all systems."
+ (should (cj/executable-exists-p "ls")))
+
+(ert-deftest test-system-lib-executable-exists-p-normal-diff-exists-returns-path ()
+ "Test that diff program exists and is detected.
+
+Tests specifically for diff which we use in our diff functionality."
+ (should (cj/executable-exists-p "diff")))
+
+;;; Boundary Cases
+
+(ert-deftest test-system-lib-executable-exists-p-boundary-empty-string-returns-nil ()
+ "Test that empty string returns nil.
+
+Boundary case: empty string is not a valid program name."
+ (should-not (cj/executable-exists-p "")))
+
+(ert-deftest test-system-lib-executable-exists-p-boundary-whitespace-only-returns-nil ()
+ "Test that whitespace-only string returns nil.
+
+Boundary case: strings containing only whitespace are not valid programs."
+ (should-not (cj/executable-exists-p " ")))
+
+(ert-deftest test-system-lib-executable-exists-p-boundary-absolute-path-returns-path ()
+ "Test that absolute path to executable returns the path.
+
+Boundary case: executable-find accepts both program names and full paths."
+ (should (cj/executable-exists-p "/usr/bin/ls")))
+
+;;; Error Cases
+
+(ert-deftest test-system-lib-executable-exists-p-error-nil-input-returns-nil ()
+ "Test that nil input returns nil gracefully.
+
+Error case: nil is not a valid program name."
+ (should-not (cj/executable-exists-p nil)))
+
+(ert-deftest test-system-lib-executable-exists-p-error-number-input-returns-nil ()
+ "Test that numeric input returns nil gracefully.
+
+Error case: number is not a valid program name."
+ (should-not (cj/executable-exists-p 42)))
+
+(ert-deftest test-system-lib-executable-exists-p-error-nonexistent-program-returns-nil ()
+ "Test that nonexistent program returns nil.
+
+Error case: program that definitely doesn't exist in PATH."
+ (should-not (cj/executable-exists-p "this-program-definitely-does-not-exist-xyz123")))
+
+(ert-deftest test-system-lib-executable-exists-p-error-special-characters-returns-nil ()
+ "Test that program name with special characters returns nil.
+
+Error case: invalid characters in program name."
+ (should-not (cj/executable-exists-p "program-with-$pecial-ch@rs")))
+
+(provide 'test-system-lib-executable-exists-p)
+;;; test-system-lib-executable-exists-p.el ends here