Merge branch 'ob-shell-cleanup-tests'

This commit is contained in:
Matthew Trzcinski 2023-01-11 11:16:53 -05:00
commit 4f319088ba
2 changed files with 243 additions and 218 deletions

View File

@ -1,88 +0,0 @@
#+Title: a collection of examples for ob-shell tests
#+OPTIONS: ^:nil
* Sample data structures
#+NAME: sample_array
| one |
| two |
| three |
#+NAME: sample_mapping_table
| first | one |
| second | two |
| third | three |
#+NAME: sample_big_table
| bread | 2 | kg |
| spaghetti | 20 | cm |
| milk | 50 | dl |
* Array tests
:PROPERTIES:
:ID: 0ba56632-8dc1-405c-a083-c204bae477cf
:END:
** Generic shell: no arrays
#+begin_src sh :exports results :results output :var array=sample_array
echo ${array}
#+end_src
#+RESULTS:
: one two three
** Bash shell: support for arrays
Bash will see a simple indexed array. In this test, we check that the
returned value is indeed only the first item of the array, as opposed to
the generic serialiation that will return all elements of the array as
a single string.
#+begin_src bash :exports results :results output :var array=sample_array
echo ${array}
#+end_src
#+RESULTS:
: one
* Associative array tests (simple map)
:PROPERTIES:
:ID: bec1a5b0-4619-4450-a8c0-2a746b44bf8d
:END:
** Generic shell: no special handing
The shell will see all values as a single string.
#+begin_src sh :exports results :results output :var table=sample_mapping_table
echo ${table}
#+end_src
#+RESULTS:
: first one second two third three
** Bash shell: support for associative arrays
Bash will see a table that contains the first column as the 'index'
of the associative array, and the second column as the value.
#+begin_src bash :exports :results output results :var table=sample_mapping_table
echo ${table[second]}
#+end_src
#+RESULTS:
: two
* Associative array tests (more than 2 columns)
:PROPERTIES:
:ID: 82320a48-3409-49d7-85c9-5de1c6d3ff87
:END:
** Generic shell: no special handing
#+begin_src sh :exports results :results output :var table=sample_big_table
echo ${table}
#+end_src
#+RESULTS:
: bread 2 kg spaghetti 20 cm milk 50 dl
** Bash shell: support for associative arrays with lists
Bash will see an associative array that contains each row as a single
string. Bash cannot handle lists in associative arrays.
#+begin_src bash :exports results :results output :var table=sample_big_table
echo ${table[spaghetti]}
#+end_src
#+RESULTS:
: 20 cm

View File

@ -18,102 +18,193 @@
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
;;; Comment:
;; Template test file for Org tests
;; See testing/README for how to run tests.
;;; Requirements:
;;; Code:
(org-test-for-executable "sh")
(require 'ob-core)
(unless (featurep 'ob-shell)
(signal 'missing-test-dependency "Support for Shell code blocks"))
(org-test-for-executable "sh")
;;; Code:
(ert-deftest test-ob-shell/dont-insert-spaces-on-expanded-bodies ()
"Expanded shell bodies should not start with a blank line
unless the body of the tangled block does."
"Expanded shell bodies should not start with a blank line unless
the body of the tangled block does."
(should-not (string-match "^[\n\r][\t ]*[\n\r]"
(org-babel-expand-body:generic "echo 2" '())))
(org-babel-expand-body:generic "echo 2" '())))
(should (string-match "^[\n\r][\t ]*[\n\r]"
(org-babel-expand-body:generic "\n\necho 2" '()))))
(org-babel-expand-body:generic "\n\necho 2" '()))))
(ert-deftest test-ob-shell/dont-error-on-empty-results ()
"Was throwing an elisp error when shell blocks threw errors and
returned empty results."
(should (null (org-babel-execute:sh "ls NoSuchFileOrDirectory.txt" nil))))
"Empty results should not cause a Lisp error."
(should (null (org-babel-execute:sh "" nil))))
(ert-deftest test-ob-shell/session ()
"This also tests `org-babel-comint-with-output' in
ob-comint.el, which was not previously tested."
(let ((res (org-babel-execute:sh "echo 1; echo 2" '((:session . "yes")))))
(should res)
(should (listp res)))
;; Test multi-line input.
(let ((result (org-babel-execute:sh
"if true \n then \n echo yes \n fi"
'((:session . "yes")))))
(ert-deftest test-ob-shell/dont-error-on-babel-error ()
"Errors within Babel execution should not cause Lisp errors."
(if (should (null (org-babel-execute:sh "ls NoSuchFileOrDirectory.txt" nil)))
(kill-buffer "*Org-Babel Error Output*")))
(ert-deftest test-ob-shell/session-single-return-returns-string ()
"Sessions with a single result should return a string."
(let* ((session-name "test-ob-shell/session-evaluation-single-return-returns-string")
(kill-buffer-query-functions nil)
(result (org-babel-execute:sh
(format "echo %s" session-name)
`((:session . ,session-name)))))
(should result)
(should (string= "yes" result))))
(if (should (string= session-name result))
(kill-buffer session-name))))
; A list of tests using the samples in ob-shell-test.org
(ert-deftest ob-shell/generic-uses-no-arrays ()
"No arrays for generic"
(org-test-at-id "0ba56632-8dc1-405c-a083-c204bae477cf"
(org-babel-next-src-block)
(ert-deftest test-ob-shell/session-multiple-returns-returns-list ()
"Sessions with multiple results should return a list."
(let* ((session-name "test-ob-shell/session-multiple-returns-returns-list")
(kill-buffer-query-functions nil)
(result (org-babel-execute:sh
"echo 1; echo 2"
`((:session . ,session-name)))))
(should result)
(should (listp result))
(if (should (equal '((1) (2)) result))
(kill-buffer session-name))))
(ert-deftest test-ob-shell/generic-uses-no-arrays ()
"Test generic serialization of array into a single string."
(org-test-with-temp-text
" #+NAME: sample_array
| one |
| two |
| three |
#+begin_src sh :exports results :results output :var array=sample_array
echo ${array}
<point>
#+end_src"
(should (equal "one two three" (org-trim (org-babel-execute-src-block))))))
(ert-deftest ob-shell/bash-uses-arrays ()
"Bash arrays"
(org-test-at-id "0ba56632-8dc1-405c-a083-c204bae477cf"
(org-babel-next-src-block 2)
(ert-deftest test-ob-shell/bash-uses-arrays ()
"Bash sees named array as a simple indexed array.
In this test, we check that the returned value is indeed only the
first item of the array, as opposed to the generic serialiation
that will return all elements of the array as a single string."
(org-test-with-temp-text
"#+NAME: sample_array
| one |
| two |
| three |
#+begin_src bash :exports results :results output :var array=sample_array
echo ${array}
<point>
#+end_src"
(should (equal "one" (org-trim (org-babel-execute-src-block))))))
(ert-deftest ob-shell/generic-uses-no-assoc-arrays ()
"No associative arrays for generic"
(should
(equal "first one second two third three"
(org-test-at-id
"bec1a5b0-4619-4450-a8c0-2a746b44bf8d"
(org-babel-next-src-block)
(org-trim (org-babel-execute-src-block)))))
(should
(equal "bread 2 kg spaghetti 20 cm milk 50 dl"
(org-test-at-id
"82320a48-3409-49d7-85c9-5de1c6d3ff87"
(org-babel-next-src-block)
(org-trim (org-babel-execute-src-block))))))
(ert-deftest test-ob-shell/generic-uses-no-assoc-arrays-simple-map ()
"Generic shell: no special handing for key-value mapping table
(ert-deftest ob-shell/bash-uses-assoc-arrays ()
"Bash associative arrays"
(should
(equal "two"
(org-test-at-id
"bec1a5b0-4619-4450-a8c0-2a746b44bf8d"
(org-babel-next-src-block 2)
(org-trim (org-babel-execute-src-block)))))
;; Bash associative arrays as strings for the row.
(should
(equal "20 cm"
(org-test-at-id
"82320a48-3409-49d7-85c9-5de1c6d3ff87"
(org-babel-next-src-block 2)
(org-trim (org-babel-execute-src-block))))))
No associative arrays for generic. The shell will see all values
as a single string."
(org-test-with-temp-text
"#+NAME: sample_mapping_table
| first | one |
| second | two |
| third | three |
(ert-deftest ob-shell/simple-list ()
"Test list variables in shell."
;; With bash, a list is turned into an array.
#+begin_src sh :exports results :results output :var table=sample_mapping_table
echo ${table}
<point>
#+end_src"
(should
(equal "first one second two third three"
(org-trim (org-babel-execute-src-block))))))
(ert-deftest test-ob-shell/generic-uses-no-assoc-arrays-3-columns ()
"Associative array tests (more than 2 columns)
No associative arrays for generic. The shell will see all values
as a single string."
(org-test-with-temp-text
"#+NAME: sample_big_table
| bread | 2 | kg |
| spaghetti | 20 | cm |
| milk | 50 | dl |
#+begin_src sh :exports results :results output :var table=sample_big_table
echo ${table}
<point>
#+end_src"
(should
(equal "bread 2 kg spaghetti 20 cm milk 50 dl"
(org-trim (org-babel-execute-src-block))))))
(ert-deftest test-ob-shell/bash-uses-assoc-arrays ()
"Bash shell: support for associative arrays
Bash will see a table that contains the first column as the
'index' of the associative array, and the second column as the
value. "
(org-test-with-temp-text
"#+NAME: sample_mapping_table
| first | one |
| second | two |
| third | three |
#+begin_src bash :exports :results output results :var table=sample_mapping_table
echo ${table[second]}
<point>
#+end_src "
(should
(equal "two"
(org-trim (org-babel-execute-src-block))))))
(ert-deftest test-ob-shell/bash-uses-assoc-arrays-with-lists ()
"Bash shell: support for associative arrays with lists
Bash will see an associative array that contains each row as a single
string. Bash cannot handle lists in associative arrays."
(org-test-with-temp-text
"#+NAME: sample_big_table
| bread | 2 | kg |
| spaghetti | 20 | cm |
| milk | 50 | dl |
#+begin_src bash :exports results :results output :var table=sample_big_table
echo ${table[spaghetti]}
<point>
#+end_src"
(should
(equal "20 cm"
(org-trim (org-babel-execute-src-block))))))
(ert-deftest test-ob-shell/simple-list ()
"Test list variables."
;; bash: a list is turned into an array
(should
(equal "2"
(org-test-with-temp-text
"#+BEGIN_SRC bash :results output :var l='(1 2)\necho ${l[1]}\n#+END_SRC"
(org-trim (org-babel-execute-src-block)))))
;; On sh, it is a string containing all values.
(org-test-with-temp-text
"#+BEGIN_SRC bash :results output :var l='(1 2)
echo ${l[1]}
#+END_SRC"
(org-trim (org-babel-execute-src-block)))))
;; sh: a list is a string containing all values
(should
(equal "1 2"
(org-test-with-temp-text
"#+BEGIN_SRC sh :results output :var l='(1 2)\necho ${l}\n#+END_SRC"
(org-trim (org-babel-execute-src-block))))))
(org-test-with-temp-text
"#+BEGIN_SRC sh :results output :var l='(1 2)
echo ${l}
#+END_SRC"
(org-trim (org-babel-execute-src-block))))))
(ert-deftest ob-shell/remote-with-stdin-or-cmdline ()
(ert-deftest test-ob-shell/remote-with-stdin-or-cmdline ()
"Test :stdin and :cmdline with a remote directory."
;; We assume `default-directory' is a local directory.
(skip-unless (not (memq system-type '(ms-dos windows-nt))))
@ -160,20 +251,27 @@ ob-comint.el, which was not previously tested."
(org-trim (org-babel-execute-src-block))))
(expected (concat "ARGS: --verbose 23 71"
"\nhello tramp from " (file-local-name default-directory))))
(should (equal result expected)))))))
(if (should (equal result expected))
(kill-matching-buffers (format "\\*tramp/mock\\s-%s\\*" system-name) t t)))))))
(ert-deftest ob-shell/results-table ()
(ert-deftest test-ob-shell/results-table ()
"Test :results table."
(should
(equal '(("I \"want\" it all"))
(org-test-with-temp-text
"#+BEGIN_SRC sh :results table\necho 'I \"want\" it all'\n#+END_SRC"
(org-babel-execute-src-block)))))
(org-test-with-temp-text
"#+BEGIN_SRC sh :results table
echo 'I \"want\" it all'
#+END_SRC"
(org-babel-execute-src-block)))))
(ert-deftest ob-shell/results-list ()
(ert-deftest test-ob-shell/results-list ()
"Test :results list."
(org-test-with-temp-text
"#+BEGIN_SRC sh :results list\necho 1\necho 2\necho 3\n#+END_SRC"
"#+BEGIN_SRC sh :results list
echo 1
echo 2
echo 3
#+END_SRC"
(should
(equal '((1) (2) (3))
(org-babel-execute-src-block)))
@ -184,88 +282,103 @@ ob-comint.el, which was not previously tested."
"- 1\n- 2\n- 3\n"
(buffer-substring-no-properties (point) (point-max))))))
;;; Standard output
(ert-deftest ob-shell/standard-output-after-success ()
(ert-deftest test-ob-shell/standard-output-after-success ()
"Test standard output after exiting with a zero code."
(should (= 1
(org-babel-execute:sh
"echo 1" nil))))
(ert-deftest ob-shell/standard-output-after-failure ()
(ert-deftest test-ob-shell/standard-output-after-failure ()
"Test standard output after exiting with a non-zero code."
(should (= 1
(org-babel-execute:sh
"echo 1; exit 2" nil))))
(if
(should (= 1
(org-babel-execute:sh
"echo 1; exit 2" nil)))
(kill-buffer "*Org-Babel Error Output*")))
;;; Standard error
(ert-deftest ob-shell/error-output-after-success ()
"Test that standard error shows in the error buffer, alongside the
exit code, after exiting with a zero code."
(should
(string= "1
(ert-deftest test-ob-shell/error-output-after-success ()
"Test that standard error shows in the error buffer, alongside
the exit code, after exiting with a zero code."
(if
(should
(string= "1
[ Babel evaluation exited with code 0 ]"
(progn (org-babel-eval-wipe-error-buffer)
(org-babel-execute:sh
"echo 1 >&2" nil)
(with-current-buffer org-babel-error-buffer-name
(buffer-string))))))
(progn (org-babel-eval-wipe-error-buffer)
(org-babel-execute:sh
"echo 1 >&2" nil)
(with-current-buffer org-babel-error-buffer-name
(buffer-string)))))
(kill-buffer "*Org-Babel Error Output*")))
(ert-deftest ob-shell/error-output-after-failure ()
"Test that standard error shows in the error buffer, alongside the
exit code, after exiting with a non-zero code."
(should
(string= "1
(ert-deftest test-ob-shell/error-output-after-failure ()
"Test that standard error shows in the error buffer, alongside
the exit code, after exiting with a non-zero code."
(if
(should
(string= "1
[ Babel evaluation exited with code 2 ]"
(progn (org-babel-eval-wipe-error-buffer)
(org-babel-execute:sh
"echo 1 >&2; exit 2" nil)
(with-current-buffer org-babel-error-buffer-name
(buffer-string))))))
(progn (org-babel-eval-wipe-error-buffer)
(org-babel-execute:sh
"echo 1 >&2; exit 2" nil)
(with-current-buffer org-babel-error-buffer-name
(buffer-string)))))
(kill-buffer "*Org-Babel Error Output*")))
(ert-deftest ob-shell/error-output-after-failure-multiple ()
(ert-deftest test-ob-shell/error-output-after-failure-multiple ()
"Test that multiple standard error strings show in the error
buffer, alongside multiple exit codes."
(should
(string= "1
(if
(should
(string= "1
[ Babel evaluation exited with code 2 ]
3
[ Babel evaluation exited with code 4 ]"
(progn (org-babel-eval-wipe-error-buffer)
(org-babel-execute:sh
"echo 1 >&2; exit 2" nil)
(org-babel-execute:sh
"echo 3 >&2; exit 4" nil)
(with-current-buffer org-babel-error-buffer-name
(buffer-string))))))
(progn (org-babel-eval-wipe-error-buffer)
(org-babel-execute:sh
"echo 1 >&2; exit 2" nil)
(org-babel-execute:sh
"echo 3 >&2; exit 4" nil)
(with-current-buffer org-babel-error-buffer-name
(buffer-string)))))
(kill-buffer "*Org-Babel Error Output*")))
;;; Exit codes
(ert-deftest ob-shell/exit-code ()
(ert-deftest test-ob-shell/exit-code ()
"Test that the exit code shows in the error buffer after exiting
with a non-zero return code."
(should
(string= "[ Babel evaluation exited with code 1 ]"
(progn (org-babel-eval-wipe-error-buffer)
(org-babel-execute:sh
"exit 1" nil)
(with-current-buffer org-babel-error-buffer-name
(buffer-string))))))
(if
(should
(string= "[ Babel evaluation exited with code 1 ]"
(progn (org-babel-eval-wipe-error-buffer)
(org-babel-execute:sh
"exit 1" nil)
(with-current-buffer org-babel-error-buffer-name
(buffer-string)))))
(kill-buffer "*Org-Babel Error Output*")))
(ert-deftest ob-shell/exit-code-multiple ()
(ert-deftest test-ob-shell/exit-code-multiple ()
"Test that multiple exit codes show in the error buffer after
exiting with a non-zero return code multiple times."
(should
(string= "[ Babel evaluation exited with code 1 ]
(if
(should
(string= "[ Babel evaluation exited with code 1 ]
[ Babel evaluation exited with code 2 ]"
(progn (org-babel-eval-wipe-error-buffer)
(org-babel-execute:sh
"exit 1" nil)
(org-babel-execute:sh
"exit 2" nil)
(with-current-buffer org-babel-error-buffer-name
(buffer-string))))))
(progn (org-babel-eval-wipe-error-buffer)
(org-babel-execute:sh
"exit 1" nil)
(org-babel-execute:sh
"exit 2" nil)
(with-current-buffer org-babel-error-buffer-name
(buffer-string)))))
(kill-buffer "*Org-Babel Error Output*")))
(provide 'test-ob-shell)