summaryrefslogtreecommitdiff
path: root/tests/test-fs-list-directory-recursive-extra.el
blob: 53ce3c8d8a8d4a5b9db92d4abfbaa85cc0e66e71 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
;;; test-tool-library-fs-list-directory-recursive-extra.el --- Additional ERT tests for cj/fs-list-directory-recursive -*- lexical-binding: t; -*-

;; Author: gptel-tool-writer and cjennings
;; Keywords: tests, filesystem, tools

;;; Commentary:
;; Additional tests to verify combined filters, boundary cases,
;; symlink protection, and permission issue handling in
;; cj/fs-list-directory-recursive.

;;; Code:

(require 'ert)
(require 'f)
(require 'tool-filesystem-library)

(defvar cj/fs-extra-test--temp-dir nil "Temporary temp directory for extra fs-list-directory-recursive tests.")

(defun cj/fs-extra-test--setup ()
  "Set up temp directory for extra fs-list-directory-recursive tests."
  (setq cj/fs-extra-test--temp-dir (make-temp-file "fs-lib-test" t))
  ;; Create directory structure
  (make-directory (f-join cj/fs-extra-test--temp-dir "subdir") t)
  (make-directory (f-join cj/fs-extra-test--temp-dir "subdir2") t)
  ;; Files at root level
  (with-temp-buffer (insert "Root org file") (write-file (f-join cj/fs-extra-test--temp-dir "file1.org")))
  (with-temp-buffer (insert "Root txt file") (write-file (f-join cj/fs-extra-test--temp-dir "file2.txt")))
  ;; Files in subdirectories
  (with-temp-buffer (insert "Subdir txt file") (write-file (f-join cj/fs-extra-test--temp-dir "subdir" "file3.txt")))
  (with-temp-buffer (insert "Subdir2 org file") (write-file (f-join cj/fs-extra-test--temp-dir "subdir2" "file4.org")))
  ;; Symlink to subdir2 inside subdir (potential for loops)
  (let ((target (f-join cj/fs-extra-test--temp-dir "subdir2"))
		(link (f-join cj/fs-extra-test--temp-dir "subdir" "link-to-subdir2")))
	(ignore-errors (delete-file link))
	(make-symbolic-link target link))

  ;; Create protected directory inside subdir to test permission issues
  (let ((protected-dir (f-join cj/fs-extra-test--temp-dir "subdir" "protected-dir")))
	(make-directory protected-dir t)
	;; Remove read & execute permissions
	(set-file-modes protected-dir #o000)))

(defun cj/fs-extra-test--teardown ()
  "Clean up temp directory for extra tests."
  (when (and cj/fs-extra-test--temp-dir (file-directory-p cj/fs-extra-test--temp-dir))
	;; Reset permissions to allow deletion
	(let ((protected-dir (f-join cj/fs-extra-test--temp-dir "subdir" "protected-dir")))
	  (when (file-exists-p protected-dir)
		(set-file-modes protected-dir #o755)))
	(delete-directory cj/fs-extra-test--temp-dir t))
  (setq cj/fs-extra-test--temp-dir nil))

(ert-deftest test-cj/fs-list-directory-recursive-normal-combined-filter-maxdepth ()
  "Normal: recursive listing combining extension filter and max depth."
  (cj/fs-extra-test--setup)
  (unwind-protect
	  (let* ((filter-fn (lambda (fi)
						  (string-suffix-p ".org" (f-filename (plist-get fi :path)))))
			 ;; max-depth 1 means root directory only, no recursion into subdirs
			 (files (cj/fs-list-directory-recursive cj/fs-extra-test--temp-dir filter-fn 1)))
		;; Should find only root level org files, not ones nested
		(should (cl-some (lambda (fi) (string= (f-filename (plist-get fi :path)) "file1.org")) files))
		(should-not (cl-some (lambda (fi) (string= (f-filename (plist-get fi :path)) "file4.org")) files)))
	(cj/fs-extra-test--teardown)))

(ert-deftest test-cj/fs-list-directory-recursive-boundary-max-depth-zero ()
  "Boundary: max depth zero lists no files (no recursion)."
  (cj/fs-extra-test--setup)
  (unwind-protect
	  (let ((files (cj/fs-list-directory-recursive cj/fs-extra-test--temp-dir nil 0)))
		;; Should be empty as depth 0 means no entries processed
		(should (equal files nil)))
	(cj/fs-extra-test--teardown)))

(ert-deftest test-cj/fs-list-directory-recursive-error-negative-max-depth ()
  "Error: negative max depth results in error."
  (cj/fs-extra-test--setup)
  (unwind-protect
	  (should-error (cj/fs-list-directory-recursive cj/fs-extra-test--temp-dir nil -1))
	(cj/fs-extra-test--teardown)))

(ert-deftest test-cj/fs-list-directory-recursive-boundary-symlink-no-infinite-loop ()
  "Boundary: symlinked directories do not cause infinite recursion."
  (cj/fs-extra-test--setup)
  (unwind-protect
	  (let ((files (cj/fs-list-directory-recursive cj/fs-extra-test--temp-dir nil 5)))
		;; There should be files from subdirs, but no infinite loop crashes
		(should (cl-some (lambda (fi) (string= (f-filename (plist-get fi :path)) "file4.org")) files))
		(should (cl-some (lambda (fi) (string= (f-filename (plist-get fi :path)) "file1.org")) files)))
	(cj/fs-extra-test--teardown)))

(ert-deftest test-cj/fs-list-directory-recursive-normal-permission-issue-handling ()
  "Normal: files in directories with permission issues are handled gracefully."
  (cj/fs-extra-test--setup)
  (unwind-protect
	  (let ((caught-warning nil))
		(cl-letf (((symbol-function 'message)
				   (lambda (&rest args)
					 (when (string-match "Warning:" (apply #'format args))
					   (setq caught-warning t)))))
		  (cj/fs-list-directory-recursive cj/fs-extra-test--temp-dir nil 5)
		  (should caught-warning)))
	(cj/fs-extra-test--teardown)))

(provide 'test-tool-library-fs-list-directory-recursive-extra)
;;; test-tool-library-fs-list-directory-recursive-extra.el ends here