3.5 erts files

Many relevant Emacs tests depend on comparing the contents of a buffer before and after executing a particular function. These tests can be written the normal way—making a temporary buffer, inserting the “before” text, running the function, and then comparing with the expected “after” text. However, this often leads to test code that’s pretty difficult to read and write, especially when the text in question is multi-line.

So ert provides a function called ert-test-erts-file that takes two parameters: the name of a specially-formatted erts file, and (optionally) a function that performs the transform.

These erts files can be edited with the erts-mode major mode.

An erts file is divided into sections by the (‘=-=’) separator.

Here’s an example file containing two tests:

Name: flet

=-=
(cl-flet ((bla (x)
(* x x)))
(bla 42))
=-=
(cl-flet ((bla (x)
            (* x x)))
  (bla 42))
=-=-=

Name: defun

=-=
(defun x ()
  (print (quote ( thingy great
                  stuff))))
=-=-=

A test starts with a line containing just ‘=-=’ and ends with a line containing just ‘=-=-=’. The test may be preceded by freeform text (for instance, comments), and also name/value pairs (see below for a list of them).

If there is a line with ‘=-=’ inside the test, that designates the start of the “after” text. Otherwise, the “before” and “after” texts are assumed to be identical, which you typically see when writing indentation tests.

ert-test-erts-file puts the “before” section into a temporary buffer, calls the transform function, and then compares with the “after” section.

Here’s an example usage:

(ert-test-erts-file "elisp.erts"
                    (lambda ()
                      (emacs-lisp-mode)
                      (indent-region (point-min) (point-max))))

A list of the name/value specifications that can appear before a test follows. The general syntax is ‘Name: Value’, but continuation lines can be used (along the same lines as in mail—subsequent lines that start with a space are part of the value).

Name: foo
Code: (indent-region
        (point-min) (point-max))
Name

All tests should have a name. This name will appear in ERT output if the test fails, and helps to identify the failing test.

Code

This is the code that will be run to do the transform. This can also be passed in via the ert-test-erts-file call, but ‘Code’ overrides that. It’s used not only in the following test, but in all subsequent tests in the file (until overridden by another ‘Code’ specification).

No-Before-Newline
No-After-Newline

These specifications say whether the “before” or “after” portions have a newline at the end. (This would otherwise be impossible to specify.)

Point-Char

Sometimes it’s useful to be able to put point at a specific place before executing the transform function. ‘Point-Char: |’ will make ert-test-erts-file place point where ‘|’ is in the “before” form (and remove that character), and will check that it’s where the ‘|’ character is in the “after” form (and issue a test failure if that isn’t the case). (This is used in all subsequent tests, unless overridden by a new ‘Point-Char’ spec.)

Skip

If this is present and value is a form that evaluates to a non-nil value, the test will be skipped.

If you need to use the literal line single line ‘=-=’ in a test section, you can quote it with a ‘\’ character.