org-mode/testing
Stefan Monnier 1a5e3f931c
testing: Make all files use `lexical-binding`
Mainly, add the corresponding cookie, but also add various `require`s
so that the compiler knows which vars should be trated as dynbound.
This does not fix all the warnings, but does try to eliminate
all those about "unused" variables.  For the variables truly unused,
the patch usually adds an underscore to their name to silence the warning.

Some of the fixes affect files which already used `lexical-binding`.
Not sure why the test worked before: maybe because the tests were run
without compiling them first (which could cause some of the
missing `require`d packages to be autoloaded before we got to the
problematic code, thus hiding the problem)?

I found some suspicious code, for which I added FIXMEs.

There are also a few changes to the main files.

* lisp/org-protocol.el (org-protocol-check-filename-for-protocol):
Don't call `server-edit` if it's not yet defined.  [ Needed to get
the tests to pass. ]

* lisp/ob-core.el (org-babel-temporary-directory)
(org-babel-temporary-stable-directory): Always define (and use nil
if we don't want to create a directory for it).  Simplify the code based
on the fact that (defvar V E) only evaluates E if V is not yet `boundp`.
(org-babel-temp-file, org-babel-temp-stable-file)
(org-babel-remove-temporary-directory)
(org-babel-remove-temporary-stable-directory): Adjust accordingly.

* lisp/org.el (org-log-beginning): Add FIXME.

* testing/org-test.el: Require `org` and `org-id`.
(org-id-locations-file): Don't `defconst` it.
(org-test-at-id, org-test-in-example-file, org-test-at-marker)
(org-test-with-temp-text, org-test-with-temp-text-in-file): Move edebug
specs into `declare` (and simplify them).
(org-test-with-tramp-remote-dir--worker): Declare dynbound tramp vars.
(org--compile-when): Fix quoting of `exp`.
(org-test-load): Tweak regexps.

* testing/org-batch-test-init.el: Tweak regexp, remove dead code and
add a FIXME about it.

* testing/lisp/test-ox.el: Require `ox` instead of
erroring out if it's not already loaded.  Also require `org-inlinetask`.
(org-test-with-parsed-data): Silence warnings when `info` is not used.
(test-org-export/bind-keyword): Add FIXME.

* testing/lisp/test-ox-publish.el: Require `org-test` and `ox-publish`.
(test-org-publish/resolve-external-link): Expose lambdas to
the compiler.  Remove unused var `ids`.
(test-org-publish/get-project-from-filename): Remove unused var `file`.

* testing/lisp/test-org.el: Require `org-macs`, `org`,
`org-inlinetask`, `org-refile`, and `org-agenda`.
(test-org/org-read-date): Declare `org-time-was-given` as dynbound.
(test-org/set-regexps-and-options): Add FIXME.

* testing/lisp/test-org-timer.el: Require `org-timer`.

* testing/lisp/test-org-table.el: Require `ox`.

* testing/lisp/test-org-protocol.el: Require `org-protocol` instead of
erroring out if it's not already loaded.  Also require `capture`, and
add missing `provide` statement.

* testing/lisp/test-org-pcomplete.el: Require `org`.

* testing/lisp/test-org-list.el: Require `org-list` and `org`.

* testing/lisp/test-org-lint.el: Require `org-footnote` and `org-lint`.

* testing/lisp/test-org-footnote.el: Require `org-footnote`.

* testing/lisp/test-org-element.el: Require `org-element` instead of
erroring out if it's not already loaded.  Also require `org` and
`org-inlinetask`.

* testing/lisp/test-org-duration.el: Require `org-duration`.

* testing/lisp/test-org-datetree.el: Require `org-datetree`.

* testing/lisp/test-org-colview.el: Require `org-colview`,
`org-duration`, and `org-inlinetask`.

* testing/lisp/test-org-clock.el: Require `org-duration` and `org-clock`.

* testing/lisp/test-org-archive.el: Require `org-archive`.

* testing/lisp/test-org-agenda.el
(test-org-agenda/bulk-custom-arg-func): Add FIXME.

* testing/lisp/test-ol.el: Require `ol` and `org-id`.
(test-org-link/store-link): Declare `org-store-link-props` and add FIXME.

* testing/lisp/test-oc.el (test-org-cite/export-capability): Add FIXME.

* testing/lisp/test-ob.el: Require `ob-core`, `org-src`, `ob-ref`,
and `org-table`.
(test-ob/eval-header-argument): Rename `foo` to `test-ob--foo` and
declare it as dynbound.
(test-ob/blocks-with-spaces, test-ob/specific-colnames): Add FIXME.
(test-ob/noweb-expansions-in-cache):
Declare `noweb-expansions-in-cache-var` as dynbound.

* testing/lisp/test-ob-tangle.el: Require `org` and `ob-tangle`.

* testing/lisp/test-ob-shell.el:
* testing/lisp/test-ob-python.el: Require `ob-core`.

* testing/lisp/test-ob-lob.el: Require `ob-lob`.
(temporary-value-for-test): Declare as dynbound.

* testing/lisp/test-ob-plantuml.el: Require `ob-plantuml` instead of
erroring out if it's not already loaded.
* testing/lisp/test-ob-lilypond.el: Require `ob-lilypond` instead of
erroring out if it's not already loaded.  Use `with-current-buffer`.

* testing/lisp/test-ob-julia.el: Require `ob-core`.

* testing/lisp/test-ob-java.el (org-babel-temporary-directory):
Remove dead code now that `org-babel-temporary-directory` is always bound.

* testing/lisp/test-ob-exp.el: Require `ob-exp`, `org-src`, and `org-test`.
(ob-exp/evaluate-all-executables-in-order):
Declare `*evaluation-collector*` as dynbound.

* testing/lisp/test-ob-emacs-lisp.el (ob-emacs-lisp/dynamic-lexical-edit)
(ob-emacs-lisp/dynamic-lexical-execute):
Rename dynbound var to `ob-emacs--x` and declare it as such.

* testing/lisp/test-ob-R.el: Require `ob-core`.
(ess-ask-for-ess-directory, ess-history-file): Declare vars.
2022-09-15 19:17:19 +08:00
..
examples testing: Make all files use `lexical-binding` 2022-09-15 19:17:19 +08:00
jump@820bb7d81b
lisp testing: Make all files use `lexical-binding` 2022-09-15 19:17:19 +08:00
.gitignore
README Change bracket link escape syntax 2019-03-10 18:00:36 +01:00
org-batch-test-init.el testing: Make all files use `lexical-binding` 2022-09-15 19:17:19 +08:00
org-test.el testing: Make all files use `lexical-binding` 2022-09-15 19:17:19 +08:00

README

# -*- mode:org -*-
#+TITLE: Org mode Testing
#+PROPERTY: header-args:emacs-lisp :results silent

* Dependencies

The only dependency is [[http://www.emacswiki.org/emacs/ErtTestLibrary][ERT]] the Emacs testing library which ships with
Emacs24.  If you are running an older version of Emacs and don't
already have ERT installed it can be installed from its old [[https://github.com/ohler/ert][git
repository]].

* Non-interactive batch testing from the command line

The simplest way to run the Org mode test suite is from the command
line with the following invocation.  Note that the paths below are
relative to the base of the Org mode directory.

Also note that many of the current tests uses babel evaluation...

#+BEGIN_SRC sh :dir (expand-file-name "..")
  # For Emacs earlier than 24, add -L /path/to/ert
  emacs -Q --batch \
        -L lisp/ -L testing/ -L testing/lisp -l lisp/org.el \
        -l lisp/org-id.el -l testing/org-test.el \
        --eval "(progn (org-reload) (setq org-confirm-babel-evaluate nil) \
        (org-babel-do-load-languages 'org-babel-load-languages \
        '((emacs-lisp . t) (shell . t) (org . t))))" \
        -f org-test-run-batch-tests
#+END_SRC

The options in the above command are explained below.

| -Q      | ignores any personal configuration ensuring a vanilla Emacs instance is used |
| --batch | runs Emacs in "batch" mode with no gui and termination after execution       |
| -l      | loads Org mode and the Org mode test suite defined in testing/org-test.el    |
| --eval  | reloads Org mode and allows evaluation of code blocks by the tests           |
| -f      | actually runs the tests using the `org-test-run-batch-tests' function        |

* Trigger the tests with 'make'

** Recompile all

Target ~test~ can be used to trigger a test run.  The tests start
after cleaning up and recompilation.

#+BEGIN_SRC sh :dir (expand-file-name "..") :results silent
make test
#+END_SRC

See ../mk/default.mk for details.

** Test dirty

The 'dirty' targets are for recompiling without cleaning and
rebuilding everything.  This usually speeds up the recompilation
considerably.  Note that this speed up comes to the price of possibly
weird errors due to the unclean build.

The dirty target for testing is called ~test-dirty~.

#+BEGIN_SRC sh :dir (expand-file-name "..") :results silent
make test-dirty
#+END_SRC

** Select tests by regexp

Variable ~BTEST_RE~ can be set to limit the tests which are performed.
~BTEST_RE~ is interpreted as regexp.

Example:

#+begin_src shell
make BTEST_RE='test-.*-inlinetask' test-dirty
#+end_src

yields

#+begin_example
...
selected tests: test-.*-inlinetask
Running 2 tests (2017-12-28 15:04:45+0100)
   passed  1/2  test-org-export/handle-inlinetasks
   passed  2/2  test-org-inlinetask/goto-end

Ran 2 tests, 2 results as expected (2017-12-28 15:04:45+0100)
...
#+end_example

* Interactive testing from within Emacs

To run the Org mode test suite from a current Emacs instance simply
load and run the test suite with the following commands.

1) First load the test suite.
   #+BEGIN_SRC emacs-lisp :var here=(buffer-file-name)
     (add-to-list 'load-path (file-name-directory here))
     (require 'org-test)
   #+END_SRC

2) Load required Babel languages
   #+BEGIN_SRC emacs-lisp
     (org-babel-do-load-languages
      'org-babel-load-languages
      (and
       (mapc (lambda (lang) (add-to-list 'org-babel-load-languages (cons lang t)))
             '(emacs-lisp shell org))
       org-babel-load-languages))
   #+END_SRC

3) Then run the test suite.  Babel evaluation confirmation is disabled
   and ~C-c C-c~ is enabled while running the tests.
   #+BEGIN_SRC emacs-lisp
     (let (org-babel-no-eval-on-ctrl-c-ctrl-c
           org-confirm-babel-evaluate)
       (org-test-run-all-tests))
   #+END_SRC

   When a test fails, run it interactively and investigate the problem
   in the ERT results buffer.

   To run one test: Use this as a demo example of a failing test
   #+BEGIN_SRC emacs-lisp
     (ert-deftest test-org/org-link-encode-ascii-character-demo-of-fail ()
       (should (string= "%5B"  ; Expecting %5B is correct.
                        (org-link-encode "[")))
       (should (string= "%5C"  ; Expecting %5C is wrong, %5D correct.
                        (org-link-encode "]"))))
   #+END_SRC
   or evaluate the ~ert-deftest form~ of the test you want to run.
   Then ~M-x ert RET
   test-org/org-link-encode-ascii-character-demo-of-fail RET~.  When
   not visible yet switch to the ERT results buffer named ~*ert*~.
   When a test failed the ERT results buffer shows the details of the
   first ~should~ that failed.  See ~(info "(ert)Running Tests
   Interactively")~ on how to re-run, start the debugger etc.

   To run several tests: ~M-x ert RET "<your regexp here>" RET~.

   To run all tests of a single test file: ~M-x ert-delete-all-tests
   RET~ and confirm.  ~M-x load-file RET testing/lisp/<file>.el RET
   M-x ert RET t RET~.

   Consider to set
   #+BEGIN_SRC emacs-lisp
     (setq pp-escape-newlines nil)
   #+END_SRC
   before running the test when looking at ~should~ in the ERT results
   buffer.  Especially when using ~l~ to look at passed test results
   and possibly missing an appropriate setting of ~pp-escape-newlines~
   made only temporarily for the running time of the test as
   e. g. tests using ~org-test-table-target-expect-tblfm~ do.

* Troubleshooting

- If the variable ~org-babel-no-eval-on-ctrl-c-ctrl-c~ is non-nil then
  it will result in some test failure, as there are tests which rely
  on this behavior.