[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/assess 979c26b3b7 73/95: Add assess-with-filesystem
From: |
ELPA Syncer |
Subject: |
[elpa] externals/assess 979c26b3b7 73/95: Add assess-with-filesystem |
Date: |
Tue, 19 Jul 2022 15:57:35 -0400 (EDT) |
branch: externals/assess
commit 979c26b3b79785be0786f6d99f49469f8277051e
Author: Damien Cassou <damien@cassou.me>
Commit: Phillip Lord <phillip.lord@russet.org.uk>
Add assess-with-filesystem
(assess-with-filesystem SPEC &rest FORMS)
Create temporary file hierarchy according to SPEC and run FORMS.
SPEC is a list of specifications for file system entities which
are to be created.
---
.gitignore | 2 +-
assess.el | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++++
test/assess-test.el | 50 +++++++++++++++++++++++++++
3 files changed, 149 insertions(+), 1 deletion(-)
diff --git a/.gitignore b/.gitignore
index 26c5cded2f..7479b28172 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,4 +9,4 @@
*.elc
/dist
/assess-pkg.el
-
+/test/assess-test.org
diff --git a/assess.el b/assess.el
index 1460bace74..bee76dfb11 100644
--- a/assess.el
+++ b/assess.el
@@ -590,6 +590,104 @@ See also `assess-make-related-file'."
(kill-buffer ,temp-buffer))))))
;; #+end_src
+;; ** Creating Files and Directories
+;; I can write some documentation here if Phil wants to merge code below.
+;; *** Implementation
+;; #+BEGIN_SRC emacs-lisp
+(defun assess-with-filesystem--make-parent (spec path)
+ "If SPEC is a file name, create its parent directory rooted at PATH."
+ (save-match-data
+ (when (string-match "\\(.*\\)/" spec)
+ (make-directory (concat path "/" (match-string 1 spec)) t))))
+
+(defun assess-with-filesystem--init (spec &optional path)
+ "Interpret the SPEC inside PATH."
+ (setq path (or path "."))
+ (cond
+ ((listp spec)
+ (cond
+ ;; non-empty file
+ ((and (stringp (car spec))
+ (stringp (cadr spec)))
+ (when (string-match-p "/\\'" (car spec))
+ (error "Invalid syntax: `%s' - cannot create a directory with text
content" (car spec)))
+ (assess-with-filesystem--make-parent (car spec) path)
+ (with-temp-file (concat path "/" (car spec))
+ (insert (cadr spec))))
+ ;; directory
+ ((and (stringp (car spec))
+ (consp (cadr spec)))
+ (make-directory (concat path "/" (car spec)) t)
+ (mapc (lambda (s) (assess-with-filesystem--init
+ s (concat path "/" (car spec)))) (cadr spec)))
+ ;; recursive spec, this should probably never happen
+ (t (mapc (lambda (s) (assess-with-filesystem--init s path)) spec))))
+ ;; directory specified using a string
+ ((and (stringp spec)
+ (string-match-p "/\\'" spec))
+ (make-directory (concat path "/" spec) t))
+ ;; empty file
+ ((stringp spec)
+ (assess-with-filesystem--make-parent spec path)
+ (write-region "" nil (concat path "/" spec) nil 'no-message))
+ (t (error "Invalid syntax: `%s'" spec))))
+
+(defmacro assess-with-filesystem (spec &rest forms)
+ "Create temporary file hierarchy according to SPEC and run FORMS.
+
+SPEC is a list of specifications for file system entities which
+are to be created.
+
+File system entities are specified as follows:
+
+1. a string FILE is the name of file to be created
+ - if the string contains \"/\", parent directories are created
+ automatically
+ - if the string ends with \"/\", a directory is created
+2. a list of two elements (FILE CONTENT) specifies filename and the
+ content to put in the file
+ - the \"/\" rules apply in the same way as in 1., except you can not
+ create a directory this way
+3. a list where car is a string and cadr is a list (DIR SPEC) is a
+ recursive specification evaluated with DIR as current directory
+ - the \"/\" rules apply in the same way as in 1., except you can not
+ create a file this way, a directory is always created
+
+An example showing all the possibilities:
+
+ (\"empty_file\"
+ \"dir/empty_file\"
+ \"dir/subdir/\"
+ (\"non_empty_file\" \"content\")
+ (\"dir/anotherdir/non_empty_file\" \"tralala\")
+ (\"big_dir\" (\"empty_file\"
+ (\"non_empty_file\" \"content\")
+ \"subdir/empty_file\")))
+
+If we want to run some code in a directory with an empty file
+\"foo.txt\" present, we call:
+
+ (assess-with-filesystem '(\"foo\")
+ (code-here)
+ (and-some-more-forms))
+
+You should *not* depend on where exactly the hierarchy is created.
+By default, a new directory in `temporary-file-directory' is
+created and the specification is evaluated there, but this is up
+for change."
+ (declare (indent 1))
+ (let ((temp-root (make-symbol "temp-root"))
+ (old-dd (make-symbol "old-dd")))
+ `(let ((,temp-root (make-temp-file "temp-fs-" t))
+ (,old-dd default-directory))
+ (unwind-protect
+ (progn
+ (setq default-directory ,temp-root)
+ (mapc (lambda (s) (assess-with-filesystem--init s ".")) ,spec)
+ ,@forms)
+ (delete-directory ,temp-root t)
+ (setq default-directory ,old-dd)))))
+;; #+END_SRC
;; ** Indentation functions
;; There are two main ways to test indentation -- we can either take unindented
diff --git a/test/assess-test.el b/test/assess-test.el
index d3a0617d98..4fa902daf2 100644
--- a/test/assess-test.el
+++ b/test/assess-test.el
@@ -288,6 +288,56 @@ This also tests the advice on string=."
;; #+end_src
+;; ** Creating Files and Directories
+;; #+BEGIN_SRC emacs-lisp
+(ert-deftest assess-test-create-multiple-files ()
+ (assess-with-filesystem '("foo" "bar" "baz")
+ (should (file-regular-p "foo"))
+ (should (file-regular-p "bar"))
+ (should (file-regular-p "baz"))))
+
+(ert-deftest assess-test-create-multiple-directories-and-files ()
+ (assess-with-filesystem '("foo/" "bar/" "baz")
+ (should (file-directory-p "foo"))
+ (should (file-directory-p "bar"))
+ (should (file-regular-p "baz"))))
+
+(ert-deftest assess-test-create-nested-directories ()
+ (assess-with-filesystem '("foo/bar" "foo/baz/")
+ (should (file-regular-p "foo/bar"))
+ (should (file-directory-p "foo/baz"))))
+
+(defun assess-test-file-contain-p (file content)
+ "Return nil iff FILE does not contain CONTENT."
+ (and (file-regular-p file)
+ (with-temp-buffer
+ (insert-file-contents file)
+ (string-match-p content (buffer-string)))))
+
+(ert-deftest assess-test-create-non-empty-file ()
+ (assess-with-filesystem '(("foo" "amazing content"))
+ (should (assess-test-file-contain-p "foo" "amazing content"))))
+
+(ert-deftest assess-test-create-non-empty-nested-file ()
+ (assess-with-filesystem '(("foo/bar" "amazing content"))
+ (should (assess-test-file-contain-p "foo/bar" "amazing content"))))
+
+(ert-deftest assess-test-nest-files-recursively ()
+ (assess-with-filesystem '(("foo" ("bar" "baz" "bam/"))
+ ("a/b" ("c" "d/"))
+ ("x" (("y" ("z"))
+ ("content" "content")
+ "w")))
+ (should (file-regular-p "foo/bar"))
+ (should (file-regular-p "foo/baz"))
+ (should (file-regular-p "a/b/c"))
+ (should (file-regular-p "x/y/z"))
+ (should (file-regular-p "x/content"))
+ (should (file-regular-p "x/w"))
+ (should (assess-test-file-contain-p "x/content" "content"))
+ (should (file-directory-p "foo/bam"))
+ (should (file-directory-p "a/b/d"))))
+;; #+END_SRC
;; ** Indentation Tests
;; #+begin_src emacs-lisp
- [elpa] externals/assess d2885a9bd7 50/95: Update readme for 0.2 release., (continued)
- [elpa] externals/assess d2885a9bd7 50/95: Update readme for 0.2 release., ELPA Syncer, 2022/07/19
- [elpa] externals/assess f1edef3220 52/95: Move call implementation to closure, ELPA Syncer, 2022/07/19
- [elpa] externals/assess 0781fd79c4 88/95: Prepare for 0.5 release, ELPA Syncer, 2022/07/19
- [elpa] externals/assess d809f70748 53/95: Documentation for `assess-call--capture-lambda`, ELPA Syncer, 2022/07/19
- [elpa] externals/assess 4b941ebd35 57/95: Added -pkg.el file to .gitignore, ELPA Syncer, 2022/07/19
- [elpa] externals/assess 36093a2c6b 61/95: Fix keybinding for edmacro. Add test., ELPA Syncer, 2022/07/19
- [elpa] externals/assess 46834f9423 54/95: Add ability to capture calls to hooks, ELPA Syncer, 2022/07/19
- [elpa] externals/assess 74d8de749c 64/95: assess-with-temp-buffers now uses let*, ELPA Syncer, 2022/07/19
- [elpa] externals/assess fca80753d7 66/95: Kill even modified file associated buffers, ELPA Syncer, 2022/07/19
- [elpa] externals/assess df2532f2ec 56/95: Add autoload cookies, ELPA Syncer, 2022/07/19
- [elpa] externals/assess 979c26b3b7 73/95: Add assess-with-filesystem,
ELPA Syncer <=
- [elpa] externals/assess 190eab03d7 74/95: Fix debug declation in -with-temp-buffers, ELPA Syncer, 2022/07/19
- [elpa] externals/assess 1c34f2bc14 79/95: Fix error symbol declaration, ELPA Syncer, 2022/07/19
- [elpa] externals/assess 1b1ac33709 87/95: Fix travis build, ELPA Syncer, 2022/07/19
- [elpa] externals/assess 29950d8964 90/95: Merge pull request #18 from DamienCassou/typos, ELPA Syncer, 2022/07/19
- [elpa] externals/assess cb2c0361a7 91/95: Add expected failure, ELPA Syncer, 2022/07/19
- [elpa] externals/assess be539d6447 92/95: Update test framework, drop early 24, ELPA Syncer, 2022/07/19
- [elpa] externals/assess cd394f309f 49/95: Add documentation for assess-call, ELPA Syncer, 2022/07/19
- [elpa] externals/assess 38084cff73 60/95: v0.3 release, ELPA Syncer, 2022/07/19
- [elpa] externals/assess 4a5eee8ba9 62/95: Fix version number, ELPA Syncer, 2022/07/19
- [elpa] externals/assess 29e80b7540 65/95: Ensure capture function returns correct value, ELPA Syncer, 2022/07/19