byexample

Write snippets of code in your documentation and execute them as regression tests.

View project on GitHub

Terminal Emulation

byexample can use different emulation modes to process the output of the runners.

By default byexample uses a dumb terminal (+term=dumb) which is fast and works well in most cases.

But you can change this to disable emulation with +term=as-is or to enable full ANSI terminal emulation with +term=ansi.

Dumb terminal

In this mode, byexample emulates a very simple terminal, processing only the white spaces.

It does not have the concept of a cursor, does not interpret escape codes and does not break lines automatically.

Even if a geometry is defined with +geometry, the dumb terminal does not force any boundaries: the following example will print a string longer than the width of the terminal.

>>> print("aaaabbbb" * 8)      # byexample: +geometry 24x32
aaaabbbbaaaabbbbaaaabbbbaaaabbbbaaaabbbbaaaabbbbaaaabbbbaaaabbbb

White space processing

The dumb terminal removes any trailing whitespace, converts tabs to spaces and standardizes the new lines.

This suits most examples, reducing the need to add tabs into the examples or requiring the normalization of whitespace with +norm-ws.

>>> print("\tfoo\tbar\nbaz\tsaz    \rtaz")
        foo     bar
baz     saz
taz

If you need to check whitespace characters, you can use +term=as-is to disable terminal emulation.

As-is terminal

When +term=as-is is activated the output is passed as is without any modification except for standardization of new lines.

It can be useful in some special cases to check white spaces that are removed by the dumb or ANSI terminals.

>>> print("\tfoo\tbar\nbaz\tsaz    \rtaz")       # byexample: +term=as-is
	foo	bar
baz	saz    
taz

ANSI terminal

Some programs may need a real terminal or at least an emulated ANSI terminal.

byexample can emulate one capable of interpreting and emulating all the control sequences and escape codes using +term=ansi.

Note: terminal emulation is not fully supported in Python 2.7. It should work but using a modern Python version is recommended.

Removing color

If you have an example that is printing text with color, you will probably see something like:

$ echo -e "\033[31mmessage in red\033[0m"
<...>[31mmessage in red<...>[0m

To get rid of those weird symbols you can enable terminal emulation:

$ echo -e "\033[31mmessage in red\033[0m"      # byexample: +term=ansi
message in red

Terminal boundaries

Keep in mind that an emulated terminal will honor its own boundaries or geometry: if an example prints a string longer than the width of the terminal, the string will spawn multiple lines (a newline is added automatically).

>>> print("aaaabbbb" * 8)      # byexample: +term=ansi +geometry 24x32
aaaabbbbaaaabbbbaaaabbbbaaaabbbb
aaaabbbbaaaabbbbaaaabbbbaaaabbbb

This is especially useful to work with ncurses or other advanced programs.

ncurses support

Some applications use advanced terminal features (like the ones that use ncurses) and require a terminal emulator.

Examples of this are programs like less, more, top and man.

$ less test/ds/python-tutorial.v2.md # byexample: +term=ansi +rm=  +stop-on-timeout
 This is a 101 Python tutorial
 The following is an example written in Python about arithmetics
 
     ```
     >>> from __future__ import print_function
     >>> 1 + 2
     3
     ```
 
 The next examples show you about complex numbers in Python
 
     ```
     >>> 2j * 2
     4j
 
     >>> 2j + 4j
     6j
     ```
 
 <...>(END)

Try the above example without +term=ansi and see what happens.

Pagination

byexample will not emulate pagination. When the output is larger than the height of the terminal, lines that scroll off the top are discarded.

The following example prints more lines than are available in the terminal so only the last lines are shown.

>>> for i in range(1,33):       # byexample: +term=ansi +geometry=5x80
...     print("line %i" % i)
line 29
line 30
line 31
line 32

If this is a problem change the geometry: increase the count of rows that the terminal has with +geometry.

Performance

Emulation is typically 3 times slower than the normal mode (+term=dumb). Keep that in mind and try to not enable it by default.