summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorJim Porter <jporterbugs@gmail.com>2022-07-09 10:34:31 -0700
committerJim Porter <jporterbugs@gmail.com>2022-09-04 15:15:01 -0700
commit1be925faa1065af5754fc11914b56ae98dfb2a83 (patch)
tree6003dde699588471a1a801705c3ea28bf272ac9f /test
parent5af5ed6c6271a452bf37afa0e7349838960d446a (diff)
downloademacs-1be925faa1065af5754fc11914b56ae98dfb2a83.tar.gz
Simplify Eshell handle functions and add tests/documentation
* lisp/eshell/esh-arg.el (eshell-parse-argument-hook): Explain how to use 'eshell-finish-arg'. * lisp/eshell/esh-io.el (eshell-create-handles): Only call 'eshell-get-target' for stderr if necessary. (eshell-protect-handles): Use 'dotimes'. (eshell-set-output-handle): Pass HANDLES and fix an edge case with setting a duplicate TARGET. * test/lisp/eshell/eshell-tests-helpers.el (eshell-with-temp-buffer): New macro. * test/lisp/eshell/esh-cmd-tests.el (esh-cmd-test/quoted-lisp-form) (esh-cmd-test/backquoted-lisp-form) (esh-cmd-test/backquoted-lisp-form/splice): New tests. * test/lisp/eshell/eshell-tests.el (eshell-test/redirect-buffer) (eshell-test/redirect-buffer-escaped): Move to... * test/lisp/eshell/esh-io-tests.el: ... here, and add other I/O tests. * doc/misc/eshell.texi (Arguments): Add documentation for special argument types. (Input/Output): Expand documentation for redirection and pipelines.
Diffstat (limited to 'test')
-rw-r--r--test/lisp/eshell/esh-cmd-tests.el19
-rw-r--r--test/lisp/eshell/esh-io-tests.el220
-rw-r--r--test/lisp/eshell/eshell-tests-helpers.el10
-rw-r--r--test/lisp/eshell/eshell-tests.el19
4 files changed, 249 insertions, 19 deletions
diff --git a/test/lisp/eshell/esh-cmd-tests.el b/test/lisp/eshell/esh-cmd-tests.el
index 3a582965d62..92d785d7fdf 100644
--- a/test/lisp/eshell/esh-cmd-tests.el
+++ b/test/lisp/eshell/esh-cmd-tests.el
@@ -74,6 +74,25 @@ e.g. \"{(+ 1 2)} 3\" => 3"
(eshell-command-result-equal "{(+ 1 2)} 3" 3))
+;; Lisp forms
+
+(ert-deftest esh-cmd-test/quoted-lisp-form ()
+ "Test parsing of a quoted Lisp form."
+ (eshell-command-result-equal "echo #'(1 2)" '(1 2)))
+
+(ert-deftest esh-cmd-test/backquoted-lisp-form ()
+ "Test parsing of a backquoted Lisp form."
+ (let ((eshell-test-value 42))
+ (eshell-command-result-equal "echo `(answer ,eshell-test-value)"
+ '(answer 42))))
+
+(ert-deftest esh-cmd-test/backquoted-lisp-form/splice ()
+ "Test parsing of a backquoted Lisp form using splicing."
+ (let ((eshell-test-value '(2 3)))
+ (eshell-command-result-equal "echo `(1 ,@eshell-test-value)"
+ '(1 2 3))))
+
+
;; Logical operators
(ert-deftest esh-cmd-test/and-operator ()
diff --git a/test/lisp/eshell/esh-io-tests.el b/test/lisp/eshell/esh-io-tests.el
new file mode 100644
index 00000000000..6cd2dff1c13
--- /dev/null
+++ b/test/lisp/eshell/esh-io-tests.el
@@ -0,0 +1,220 @@
+;;; esh-io-tests.el --- esh-io test suite -*- lexical-binding:t -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'ert)
+(require 'ert-x)
+(require 'esh-mode)
+(require 'eshell)
+
+(require 'eshell-tests-helpers
+ (expand-file-name "eshell-tests-helpers"
+ (file-name-directory (or load-file-name
+ default-directory))))
+
+(defvar eshell-test-value nil)
+
+(defun eshell-test-file-string (file)
+ "Return the contents of FILE as a string."
+ (with-temp-buffer
+ (insert-file-contents file)
+ (buffer-string)))
+
+(defun eshell/test-output ()
+ "Write some test output separately to stdout and stderr."
+ (eshell-printn "stdout")
+ (eshell-errorn "stderr"))
+
+;;; Tests:
+
+
+;; Basic redirection
+
+(ert-deftest esh-io-test/redirect-file/overwrite ()
+ "Check that redirecting to a file in overwrite mode works."
+ (ert-with-temp-file temp-file
+ :text "old"
+ (with-temp-eshell
+ (eshell-insert-command (format "echo new > %s" temp-file)))
+ (should (equal (eshell-test-file-string temp-file) "new"))))
+
+(ert-deftest esh-io-test/redirect-file/append ()
+ "Check that redirecting to a file in append mode works."
+ (ert-with-temp-file temp-file
+ :text "old"
+ (with-temp-eshell
+ (eshell-insert-command (format "echo new >> %s" temp-file)))
+ (should (equal (eshell-test-file-string temp-file) "oldnew"))))
+
+(ert-deftest esh-io-test/redirect-file/insert ()
+ "Check that redirecting to a file in insert works."
+ (ert-with-temp-file temp-file
+ :text "old"
+ (with-temp-eshell
+ (eshell-insert-command (format "echo new >>> %s" temp-file)))
+ (should (equal (eshell-test-file-string temp-file) "newold"))))
+
+(ert-deftest esh-io-test/redirect-buffer/overwrite ()
+ "Check that redirecting to a buffer in overwrite mode works."
+ (eshell-with-temp-buffer bufname "old"
+ (with-temp-eshell
+ (eshell-insert-command (format "echo new > #<%s>" bufname)))
+ (should (equal (buffer-string) "new"))))
+
+(ert-deftest esh-io-test/redirect-buffer/append ()
+ "Check that redirecting to a buffer in append mode works."
+ (eshell-with-temp-buffer bufname "old"
+ (with-temp-eshell
+ (eshell-insert-command (format "echo new >> #<%s>" bufname)))
+ (should (equal (buffer-string) "oldnew"))))
+
+(ert-deftest esh-io-test/redirect-buffer/insert ()
+ "Check that redirecting to a buffer in insert mode works."
+ (eshell-with-temp-buffer bufname "old"
+ (goto-char (point-min))
+ (with-temp-eshell
+ (eshell-insert-command (format "echo new >>> #<%s>" bufname)))
+ (should (equal (buffer-string) "newold"))))
+
+(ert-deftest esh-io-test/redirect-buffer/escaped ()
+ "Check that redirecting to a buffer with escaped characters works."
+ (with-temp-buffer
+ (rename-buffer "eshell\\temp\\buffer" t)
+ (let ((bufname (buffer-name)))
+ (with-temp-eshell
+ (eshell-insert-command (format "echo hi > #<%s>"
+ (string-replace "\\" "\\\\" bufname))))
+ (should (equal (buffer-string) "hi")))))
+
+(ert-deftest esh-io-test/redirect-symbol/overwrite ()
+ "Check that redirecting to a symbol in overwrite mode works."
+ (let ((eshell-test-value "old"))
+ (with-temp-eshell
+ (eshell-insert-command "echo new > #'eshell-test-value"))
+ (should (equal eshell-test-value "new"))))
+
+(ert-deftest esh-io-test/redirect-symbol/append ()
+ "Check that redirecting to a symbol in append mode works."
+ (let ((eshell-test-value "old"))
+ (with-temp-eshell
+ (eshell-insert-command "echo new >> #'eshell-test-value"))
+ (should (equal eshell-test-value "oldnew"))))
+
+(ert-deftest esh-io-test/redirect-marker ()
+ "Check that redirecting to a marker works."
+ (with-temp-buffer
+ (let ((eshell-test-value (point-marker)))
+ (with-temp-eshell
+ (eshell-insert-command "echo hi > $eshell-test-value"))
+ (should (equal (buffer-string) "hi")))))
+
+(ert-deftest esh-io-test/redirect-multiple ()
+ "Check that redirecting to multiple targets works."
+ (let ((eshell-test-value "old"))
+ (eshell-with-temp-buffer bufname "old"
+ (with-temp-eshell
+ (eshell-insert-command (format "echo new > #<%s> > #'eshell-test-value"
+ bufname)))
+ (should (equal (buffer-string) "new"))
+ (should (equal eshell-test-value "new")))))
+
+(ert-deftest esh-io-test/redirect-multiple/repeat ()
+ "Check that redirecting to multiple targets works when repeating a target."
+ (let ((eshell-test-value "old"))
+ (eshell-with-temp-buffer bufname "old"
+ (with-temp-eshell
+ (eshell-insert-command
+ (format "echo new > #<%s> > #'eshell-test-value > #<%s>"
+ bufname bufname)))
+ (should (equal (buffer-string) "new"))
+ (should (equal eshell-test-value "new")))))
+
+
+;; Redirecting specific handles
+
+(ert-deftest esh-io-test/redirect-stdout ()
+ "Check that redirecting to stdout doesn't redirect stderr."
+ (eshell-with-temp-buffer bufname "old"
+ (with-temp-eshell
+ (eshell-match-command-output (format "test-output > #<%s>" bufname)
+ "stderr\n"))
+ (should (equal (buffer-string) "stdout\n")))
+ ;; Also check explicitly specifying the stdout fd.
+ (eshell-with-temp-buffer bufname "old"
+ (with-temp-eshell
+ (eshell-match-command-output (format "test-output 1> #<%s>" bufname)
+ "stderr\n"))
+ (should (equal (buffer-string) "stdout\n"))))
+
+(ert-deftest esh-io-test/redirect-stderr/overwrite ()
+ "Check that redirecting to stderr doesn't redirect stdout."
+ (eshell-with-temp-buffer bufname "old"
+ (with-temp-eshell
+ (eshell-match-command-output (format "test-output 2> #<%s>" bufname)
+ "stdout\n"))
+ (should (equal (buffer-string) "stderr\n"))))
+
+(ert-deftest esh-io-test/redirect-stderr/append ()
+ "Check that redirecting to stderr doesn't redirect stdout."
+ (eshell-with-temp-buffer bufname "old"
+ (with-temp-eshell
+ (eshell-match-command-output (format "test-output 2>> #<%s>" bufname)
+ "stdout\n"))
+ (should (equal (buffer-string) "oldstderr\n"))))
+
+(ert-deftest esh-io-test/redirect-stderr/insert ()
+ "Check that redirecting to stderr doesn't redirect stdout."
+ (eshell-with-temp-buffer bufname "old"
+ (goto-char (point-min))
+ (with-temp-eshell
+ (eshell-match-command-output (format "test-output 2>>> #<%s>" bufname)
+ "stdout\n"))
+ (should (equal (buffer-string) "stderr\nold"))))
+
+(ert-deftest esh-io-test/redirect-stdout-and-stderr ()
+ "Check that redirecting to both stdout and stderr works."
+ (eshell-with-temp-buffer bufname-1 "old"
+ (eshell-with-temp-buffer bufname-2 "old"
+ (with-temp-eshell
+ (eshell-match-command-output (format "test-output > #<%s> 2> #<%s>"
+ bufname-1 bufname-2)
+ "\\`\\'"))
+ (should (equal (buffer-string) "stderr\n")))
+ (should (equal (buffer-string) "stdout\n"))))
+
+
+;; Virtual targets
+
+(ert-deftest esh-io-test/virtual-dev-eshell ()
+ "Check that redirecting to /dev/eshell works."
+ (with-temp-eshell
+ (eshell-match-command-output "echo hi > /dev/eshell" "hi")))
+
+(ert-deftest esh-io-test/virtual-dev-kill ()
+ "Check that redirecting to /dev/kill works."
+ (with-temp-eshell
+ (eshell-insert-command "echo one > /dev/kill")
+ (should (equal (car kill-ring) "one"))
+ (eshell-insert-command "echo two > /dev/kill")
+ (should (equal (car kill-ring) "two"))
+ (eshell-insert-command "echo three >> /dev/kill")
+ (should (equal (car kill-ring) "twothree"))))
+
+;;; esh-io-tests.el ends here
diff --git a/test/lisp/eshell/eshell-tests-helpers.el b/test/lisp/eshell/eshell-tests-helpers.el
index 8f0f993447f..73abfcbb557 100644
--- a/test/lisp/eshell/eshell-tests-helpers.el
+++ b/test/lisp/eshell/eshell-tests-helpers.el
@@ -51,6 +51,16 @@ See `eshell-wait-for-subprocess'.")
(let (kill-buffer-query-functions)
(kill-buffer eshell-buffer)))))))
+(defmacro eshell-with-temp-buffer (bufname text &rest body)
+ "Create a temporary buffer containing TEXT and evaluate BODY there.
+BUFNAME will be set to the name of the temporary buffer."
+ (declare (indent 2))
+ `(with-temp-buffer
+ (insert ,text)
+ (rename-buffer "eshell-temp-buffer" t)
+ (let ((,bufname (buffer-name)))
+ ,@body)))
+
(defun eshell-wait-for-subprocess (&optional all)
"Wait until there is no interactive subprocess running in Eshell.
If ALL is non-nil, wait until there are no Eshell subprocesses at
diff --git a/test/lisp/eshell/eshell-tests.el b/test/lisp/eshell/eshell-tests.el
index 1845dba2809..d5112146c2d 100644
--- a/test/lisp/eshell/eshell-tests.el
+++ b/test/lisp/eshell/eshell-tests.el
@@ -105,25 +105,6 @@
(format template "format \"%s\" eshell-in-pipeline-p")
"nil")))
-(ert-deftest eshell-test/redirect-buffer ()
- "Check that piping to a buffer works"
- (with-temp-buffer
- (rename-buffer "eshell-temp-buffer" t)
- (let ((bufname (buffer-name)))
- (with-temp-eshell
- (eshell-insert-command (format "echo hi > #<%s>" bufname)))
- (should (equal (buffer-string) "hi")))))
-
-(ert-deftest eshell-test/redirect-buffer-escaped ()
- "Check that piping to a buffer with escaped characters works"
- (with-temp-buffer
- (rename-buffer "eshell\\temp\\buffer" t)
- (let ((bufname (buffer-name)))
- (with-temp-eshell
- (eshell-insert-command (format "echo hi > #<%s>"
- (string-replace "\\" "\\\\" bufname))))
- (should (equal (buffer-string) "hi")))))
-
(ert-deftest eshell-test/escape-nonspecial ()
"Test that \"\\c\" and \"c\" are equivalent when \"c\" is not a
special character."