emacs/test/lisp/eshell/esh-io-tests.el

394 lines
15 KiB
EmacsLisp
Raw Normal View History

;;; esh-io-tests.el --- esh-io test suite -*- lexical-binding:t -*-
2024-01-02 09:47:10 +08:00
;; Copyright (C) 2022-2024 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)
(defvar eshell-test-value-with-fun nil)
(defun eshell-test-value-with-fun ())
(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-symbol/with-function-slot ()
"Check that redirecting to a symbol with function slot set works."
(let ((eshell-test-value-with-fun))
(with-temp-eshell
(eshell-insert-command "echo hi > #'eshell-test-value-with-fun"))
(should (equal eshell-test-value-with-fun "hi"))))
(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")))))
(ert-deftest esh-io-test/redirect-subcommands ()
"Check that redirecting subcommands applies to all subcommands."
(eshell-with-temp-buffer bufname "old"
(with-temp-eshell
(eshell-insert-command (format "{echo foo; echo bar} > #<%s>" bufname)))
(should (equal (buffer-string) "foobar"))))
(ert-deftest esh-io-test/redirect-subcommands/override ()
"Check that redirecting subcommands applies to all subcommands.
Include a redirect to another location in the subcommand to
ensure only its statement is redirected."
(eshell-with-temp-buffer bufname "old"
(eshell-with-temp-buffer bufname-2 "also old"
(with-temp-eshell
(eshell-insert-command
(format "{echo foo; echo bar > #<%s>; echo baz} > #<%s>"
bufname-2 bufname)))
(should (equal (buffer-string) "bar")))
(should (equal (buffer-string) "foobaz"))))
(ert-deftest esh-io-test/redirect-subcommands/dev-null ()
"Check that redirecting subcommands applies to all subcommands.
Include a redirect to /dev/null to ensure it only applies to its
statement."
(eshell-with-temp-buffer bufname "old"
(with-temp-eshell
(eshell-insert-command
(format "{echo foo; echo bar > /dev/null; echo baz} > #<%s>"
bufname)))
(should (equal (buffer-string) "foobaz"))))
(ert-deftest esh-io-test/redirect-subcommands/interpolated ()
"Check that redirecting interpolated subcommands applies to all subcommands."
(eshell-with-temp-buffer bufname "old"
(with-temp-eshell
(eshell-insert-command
(format "echo ${echo foo; echo bar} > #<%s>" bufname)))
(should (equal (buffer-string) "foobar"))))
;; 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"))))
(ert-deftest esh-io-test/redirect-all/overwrite ()
"Check that redirecting to stdout and stderr via shorthand works."
(eshell-with-temp-buffer bufname "old"
(with-temp-eshell
(eshell-match-command-output (format "test-output &> #<%s>" bufname)
"\\`\\'"))
(should (equal (buffer-string) "stdout\nstderr\n")))
;; Also check the alternate (and less-preferred in Bash) `>&' syntax.
(eshell-with-temp-buffer bufname "old"
(with-temp-eshell
(eshell-match-command-output (format "test-output >& #<%s>" bufname)
"\\`\\'"))
(should (equal (buffer-string) "stdout\nstderr\n"))))
(ert-deftest esh-io-test/redirect-all/append ()
"Check that redirecting to stdout and stderr via shorthand works."
(eshell-with-temp-buffer bufname "old"
(with-temp-eshell
(eshell-match-command-output (format "test-output &>> #<%s>" bufname)
"\\`\\'"))
(should (equal (buffer-string) "oldstdout\nstderr\n")))
;; Also check the alternate (and less-preferred in Bash) `>>&' syntax.
(eshell-with-temp-buffer bufname "old"
(with-temp-eshell
(eshell-match-command-output (format "test-output >>& #<%s>" bufname)
"\\`\\'"))
(should (equal (buffer-string) "oldstdout\nstderr\n"))))
(ert-deftest esh-io-test/redirect-all/insert ()
"Check that redirecting to stdout and stderr via shorthand works."
(eshell-with-temp-buffer bufname "old"
(goto-char (point-min))
(with-temp-eshell
(eshell-match-command-output (format "test-output &>>> #<%s>" bufname)
"\\`\\'"))
(should (equal (buffer-string) "stdout\nstderr\nold")))
;; Also check the alternate `>>>&' syntax.
(eshell-with-temp-buffer bufname "old"
(goto-char (point-min))
(with-temp-eshell
(eshell-match-command-output (format "test-output >>>& #<%s>" bufname)
"\\`\\'"))
(should (equal (buffer-string) "stdout\nstderr\nold"))))
(ert-deftest esh-io-test/redirect-copy ()
"Check that redirecting stdout and then copying stdout to stderr works.
This should redirect both stdout and stderr to the same place."
(eshell-with-temp-buffer bufname "old"
(with-temp-eshell
(eshell-match-command-output (format "test-output > #<%s> 2>&1" bufname)
"\\`\\'"))
(should (equal (buffer-string) "stdout\nstderr\n"))))
(ert-deftest esh-io-test/redirect-copy-first ()
"Check that copying stdout to stderr and then redirecting stdout works.
This should redirect stdout to a buffer, and stderr to where
stdout originally pointed (the terminal)."
(eshell-with-temp-buffer bufname "old"
(with-temp-eshell
(eshell-match-command-output (format "test-output 2>&1 > #<%s>" bufname)
"stderr\n"))
(should (equal (buffer-string) "stdout\n"))))
Fix reference-counting of Eshell I/O handles This ensures that output targets in Eshell are only closed when Eshell is actually done with them. In particular, this means that "{ echo foo; echo bar } | rev" prints "raboof" as expected (bug#59545). * lisp/eshell/esh-io.el (eshell-create-handles): Structure the handles differently so the targets and their ref-count can be shared. (eshell-duplicate-handles): Reimplement this to share targets between the original and new handle sets. Add STEAL-P argument. (eshell-protect-handles, eshell-copy-output-handle) (eshell-interactive-output-p, eshell-output-object): Account for changes to the handle structure. (eshell-close-handle): New function... (eshell-close-handles, eshell-set-output-handle): ... use it. (eshell-get-targets): Remove. This only existed to make the previous implementation of 'eshell-duplicate-handles' work. * lisp/eshell/esh-cmd.el (eshell-with-copied-handles): New argument STEAL-P. (eshell-do-pipelines): Use STEAL-P for the last item in the pipeline. (eshell-parse-command): Don't copy handles for the last command in the list; explain why we can't use STEAL-P here. (eshell-eval-command): When queuing input, set 'eshell-command-body' and 'eshell-test-body' for the 'if' conditional (see 'eshell-do-eval'). * test/lisp/eshell/esh-io-tests.el (esh-io-test/redirect-pipe): Split into... (esh-io-test/pipeline/default, esh-io-test/pipeline/all): ... these. (esh-io-test/pipeline/subcommands): New test. * test/lisp/eshell/esh-cmd-tests.el (esh-cmd-test/for-loop-pipe) (esh-cmd-test/while-loop-pipe, esh-cmd-test/if-statement-pipe) esh-cmd-test/if-else-statement-pipe): New tests. (esh-cmd-test/while-loop): Use 'pop' to simplify the test a bit. * test/lisp/eshell/eshell-test-helpers.el (eshell-test--max-subprocess-time): Rename to... (eshell-test--max-wait-time): ... this. (eshell-wait-for): New function... (eshell-wait-for-subprocess): ... use it. * test/lisp/eshell/eshell-tests.el (eshell-test/queue-input): Fix this test. Previously, it didn't correctly verify that the original command completed. * test/lisp/eshell/em-tramp-tests.el (em-tramp-test/should-replace-command): New macro... (em-tramp-test/su-default, em-tramp-test/su-user) (em-tramp-test/su-login, em-tramp-test/sudo-shell) (em-tramp-test/sudo-user-shell, em-tramp-test/doas-shell) (em-tramp-test/doas-user-shell): ... use it.
2022-12-24 14:31:50 -08:00
;; Pipelines
(ert-deftest esh-io-test/pipeline/default ()
"Check that `|' only pipes stdout."
(skip-unless (executable-find "rev"))
(eshell-command-result-equal "test-output | rev"
Fix reference-counting of Eshell I/O handles This ensures that output targets in Eshell are only closed when Eshell is actually done with them. In particular, this means that "{ echo foo; echo bar } | rev" prints "raboof" as expected (bug#59545). * lisp/eshell/esh-io.el (eshell-create-handles): Structure the handles differently so the targets and their ref-count can be shared. (eshell-duplicate-handles): Reimplement this to share targets between the original and new handle sets. Add STEAL-P argument. (eshell-protect-handles, eshell-copy-output-handle) (eshell-interactive-output-p, eshell-output-object): Account for changes to the handle structure. (eshell-close-handle): New function... (eshell-close-handles, eshell-set-output-handle): ... use it. (eshell-get-targets): Remove. This only existed to make the previous implementation of 'eshell-duplicate-handles' work. * lisp/eshell/esh-cmd.el (eshell-with-copied-handles): New argument STEAL-P. (eshell-do-pipelines): Use STEAL-P for the last item in the pipeline. (eshell-parse-command): Don't copy handles for the last command in the list; explain why we can't use STEAL-P here. (eshell-eval-command): When queuing input, set 'eshell-command-body' and 'eshell-test-body' for the 'if' conditional (see 'eshell-do-eval'). * test/lisp/eshell/esh-io-tests.el (esh-io-test/redirect-pipe): Split into... (esh-io-test/pipeline/default, esh-io-test/pipeline/all): ... these. (esh-io-test/pipeline/subcommands): New test. * test/lisp/eshell/esh-cmd-tests.el (esh-cmd-test/for-loop-pipe) (esh-cmd-test/while-loop-pipe, esh-cmd-test/if-statement-pipe) esh-cmd-test/if-else-statement-pipe): New tests. (esh-cmd-test/while-loop): Use 'pop' to simplify the test a bit. * test/lisp/eshell/eshell-test-helpers.el (eshell-test--max-subprocess-time): Rename to... (eshell-test--max-wait-time): ... this. (eshell-wait-for): New function... (eshell-wait-for-subprocess): ... use it. * test/lisp/eshell/eshell-tests.el (eshell-test/queue-input): Fix this test. Previously, it didn't correctly verify that the original command completed. * test/lisp/eshell/em-tramp-tests.el (em-tramp-test/should-replace-command): New macro... (em-tramp-test/su-default, em-tramp-test/su-user) (em-tramp-test/su-login, em-tramp-test/sudo-shell) (em-tramp-test/sudo-user-shell, em-tramp-test/doas-shell) (em-tramp-test/doas-user-shell): ... use it.
2022-12-24 14:31:50 -08:00
"stderr\ntuodts\n"))
(ert-deftest esh-io-test/pipeline/all ()
"Check that `|&' only pipes stdout and stderr."
(skip-unless (executable-find "rev"))
(eshell-command-result-equal "test-output |& rev"
"tuodts\nrredts\n"))
Fix reference-counting of Eshell I/O handles This ensures that output targets in Eshell are only closed when Eshell is actually done with them. In particular, this means that "{ echo foo; echo bar } | rev" prints "raboof" as expected (bug#59545). * lisp/eshell/esh-io.el (eshell-create-handles): Structure the handles differently so the targets and their ref-count can be shared. (eshell-duplicate-handles): Reimplement this to share targets between the original and new handle sets. Add STEAL-P argument. (eshell-protect-handles, eshell-copy-output-handle) (eshell-interactive-output-p, eshell-output-object): Account for changes to the handle structure. (eshell-close-handle): New function... (eshell-close-handles, eshell-set-output-handle): ... use it. (eshell-get-targets): Remove. This only existed to make the previous implementation of 'eshell-duplicate-handles' work. * lisp/eshell/esh-cmd.el (eshell-with-copied-handles): New argument STEAL-P. (eshell-do-pipelines): Use STEAL-P for the last item in the pipeline. (eshell-parse-command): Don't copy handles for the last command in the list; explain why we can't use STEAL-P here. (eshell-eval-command): When queuing input, set 'eshell-command-body' and 'eshell-test-body' for the 'if' conditional (see 'eshell-do-eval'). * test/lisp/eshell/esh-io-tests.el (esh-io-test/redirect-pipe): Split into... (esh-io-test/pipeline/default, esh-io-test/pipeline/all): ... these. (esh-io-test/pipeline/subcommands): New test. * test/lisp/eshell/esh-cmd-tests.el (esh-cmd-test/for-loop-pipe) (esh-cmd-test/while-loop-pipe, esh-cmd-test/if-statement-pipe) esh-cmd-test/if-else-statement-pipe): New tests. (esh-cmd-test/while-loop): Use 'pop' to simplify the test a bit. * test/lisp/eshell/eshell-test-helpers.el (eshell-test--max-subprocess-time): Rename to... (eshell-test--max-wait-time): ... this. (eshell-wait-for): New function... (eshell-wait-for-subprocess): ... use it. * test/lisp/eshell/eshell-tests.el (eshell-test/queue-input): Fix this test. Previously, it didn't correctly verify that the original command completed. * test/lisp/eshell/em-tramp-tests.el (em-tramp-test/should-replace-command): New macro... (em-tramp-test/su-default, em-tramp-test/su-user) (em-tramp-test/su-login, em-tramp-test/sudo-shell) (em-tramp-test/sudo-user-shell, em-tramp-test/doas-shell) (em-tramp-test/doas-user-shell): ... use it.
2022-12-24 14:31:50 -08:00
(ert-deftest esh-io-test/pipeline/subcommands ()
2023-12-10 13:22:04 +01:00
"Check that all commands in a subcommand are properly piped."
Fix reference-counting of Eshell I/O handles This ensures that output targets in Eshell are only closed when Eshell is actually done with them. In particular, this means that "{ echo foo; echo bar } | rev" prints "raboof" as expected (bug#59545). * lisp/eshell/esh-io.el (eshell-create-handles): Structure the handles differently so the targets and their ref-count can be shared. (eshell-duplicate-handles): Reimplement this to share targets between the original and new handle sets. Add STEAL-P argument. (eshell-protect-handles, eshell-copy-output-handle) (eshell-interactive-output-p, eshell-output-object): Account for changes to the handle structure. (eshell-close-handle): New function... (eshell-close-handles, eshell-set-output-handle): ... use it. (eshell-get-targets): Remove. This only existed to make the previous implementation of 'eshell-duplicate-handles' work. * lisp/eshell/esh-cmd.el (eshell-with-copied-handles): New argument STEAL-P. (eshell-do-pipelines): Use STEAL-P for the last item in the pipeline. (eshell-parse-command): Don't copy handles for the last command in the list; explain why we can't use STEAL-P here. (eshell-eval-command): When queuing input, set 'eshell-command-body' and 'eshell-test-body' for the 'if' conditional (see 'eshell-do-eval'). * test/lisp/eshell/esh-io-tests.el (esh-io-test/redirect-pipe): Split into... (esh-io-test/pipeline/default, esh-io-test/pipeline/all): ... these. (esh-io-test/pipeline/subcommands): New test. * test/lisp/eshell/esh-cmd-tests.el (esh-cmd-test/for-loop-pipe) (esh-cmd-test/while-loop-pipe, esh-cmd-test/if-statement-pipe) esh-cmd-test/if-else-statement-pipe): New tests. (esh-cmd-test/while-loop): Use 'pop' to simplify the test a bit. * test/lisp/eshell/eshell-test-helpers.el (eshell-test--max-subprocess-time): Rename to... (eshell-test--max-wait-time): ... this. (eshell-wait-for): New function... (eshell-wait-for-subprocess): ... use it. * test/lisp/eshell/eshell-tests.el (eshell-test/queue-input): Fix this test. Previously, it didn't correctly verify that the original command completed. * test/lisp/eshell/em-tramp-tests.el (em-tramp-test/should-replace-command): New macro... (em-tramp-test/su-default, em-tramp-test/su-user) (em-tramp-test/su-login, em-tramp-test/sudo-shell) (em-tramp-test/sudo-user-shell, em-tramp-test/doas-shell) (em-tramp-test/doas-user-shell): ... use it.
2022-12-24 14:31:50 -08:00
(skip-unless (executable-find "rev"))
(with-temp-eshell
(eshell-match-command-output "{echo foo; echo bar} | rev"
"\\`raboof\n?")))
Fix reference-counting of Eshell I/O handles This ensures that output targets in Eshell are only closed when Eshell is actually done with them. In particular, this means that "{ echo foo; echo bar } | rev" prints "raboof" as expected (bug#59545). * lisp/eshell/esh-io.el (eshell-create-handles): Structure the handles differently so the targets and their ref-count can be shared. (eshell-duplicate-handles): Reimplement this to share targets between the original and new handle sets. Add STEAL-P argument. (eshell-protect-handles, eshell-copy-output-handle) (eshell-interactive-output-p, eshell-output-object): Account for changes to the handle structure. (eshell-close-handle): New function... (eshell-close-handles, eshell-set-output-handle): ... use it. (eshell-get-targets): Remove. This only existed to make the previous implementation of 'eshell-duplicate-handles' work. * lisp/eshell/esh-cmd.el (eshell-with-copied-handles): New argument STEAL-P. (eshell-do-pipelines): Use STEAL-P for the last item in the pipeline. (eshell-parse-command): Don't copy handles for the last command in the list; explain why we can't use STEAL-P here. (eshell-eval-command): When queuing input, set 'eshell-command-body' and 'eshell-test-body' for the 'if' conditional (see 'eshell-do-eval'). * test/lisp/eshell/esh-io-tests.el (esh-io-test/redirect-pipe): Split into... (esh-io-test/pipeline/default, esh-io-test/pipeline/all): ... these. (esh-io-test/pipeline/subcommands): New test. * test/lisp/eshell/esh-cmd-tests.el (esh-cmd-test/for-loop-pipe) (esh-cmd-test/while-loop-pipe, esh-cmd-test/if-statement-pipe) esh-cmd-test/if-else-statement-pipe): New tests. (esh-cmd-test/while-loop): Use 'pop' to simplify the test a bit. * test/lisp/eshell/eshell-test-helpers.el (eshell-test--max-subprocess-time): Rename to... (eshell-test--max-wait-time): ... this. (eshell-wait-for): New function... (eshell-wait-for-subprocess): ... use it. * test/lisp/eshell/eshell-tests.el (eshell-test/queue-input): Fix this test. Previously, it didn't correctly verify that the original command completed. * test/lisp/eshell/em-tramp-tests.el (em-tramp-test/should-replace-command): New macro... (em-tramp-test/su-default, em-tramp-test/su-user) (em-tramp-test/su-login, em-tramp-test/sudo-shell) (em-tramp-test/sudo-user-shell, em-tramp-test/doas-shell) (em-tramp-test/doas-user-shell): ... use it.
2022-12-24 14:31:50 -08:00
(ert-deftest esh-io-test/pipeline/stdin-to-head ()
"Check that standard input is sent to the head process in a pipeline."
(skip-unless (and (executable-find "tr")
(executable-find "rev")))
(with-temp-eshell
(eshell-insert-command "tr a-z A-Z | rev")
(eshell-insert-command "hello")
(eshell-send-eof-to-process)
(eshell-wait-for-subprocess)
(should (eshell-match-output "OLLEH\n"))))
;; Virtual targets
(ert-deftest esh-io-test/virtual/dev-null ()
"Check that redirecting to /dev/null works."
(with-temp-eshell
(eshell-match-command-output "echo hi > /dev/null" "\\`\\'")))
(ert-deftest esh-io-test/virtual/dev-null/multiple ()
"Check that redirecting to /dev/null works alongside other redirections."
(eshell-with-temp-buffer bufname "old"
(with-temp-eshell
(eshell-match-command-output
(format "echo new > /dev/null > #<%s>" bufname) "\\`\\'"))
(should (equal (buffer-string) "new")))
(eshell-with-temp-buffer bufname "old"
(with-temp-eshell
(eshell-match-command-output
(format "echo new > #<%s> > /dev/null" bufname) "\\`\\'"))
(should (equal (buffer-string) "new"))))
(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"))))
(ert-deftest esh-io-test/virtual/device-close ()
"Check that the close function for `eshell-function-target' works."
(let* ((data nil)
(status nil)
(eshell-virtual-targets
`(("/dev/virtual"
,(eshell-function-target-create
(lambda (d) (setq data d))
(lambda (s) (setq status s)))
nil))))
(with-temp-eshell
(eshell-insert-command "echo hello > /dev/virtual")
(should (equal data "hello"))
(should (equal status t)))))
;;; esh-io-tests.el ends here