====================================
Technical details of the cairo tests
====================================

Normalizing undefined bits in RGB24 images
------------------------------------------

Cairo ImageSurfaces using the cairo.FORMAT_RGB24 pixel format have undefined
bits inside their buffers, which leads to false mismatches when comparing two
such surfaces by their buffer contents. The test runner goes to some effort to
canonicalise the buffer contents so that equal RGB24 images compare equal:

>>> import cairo
>>> def create_surface(x1, y1, x2, y2):
...     surface = cairo.ImageSurface(cairo.FORMAT_RGB24, 100, 100)
...     ctx = cairo.Context(surface)
...     ctx.set_source_rgb(1, 1, 1)
...     ctx.paint()
...     ctx.rectangle(0, 0, 100, 100)
...     ctx.move_to(x1, y1)
...     ctx.line_to(x2, y2)
...     ctx.set_source_rgb(0, 0, 0)
...     ctx.stroke()
...     return surface

>>> sample_txt = write('sample.txt', """\
...
... .. figure:: rgb24.png
...
...     ``create_surface(25, 50, 75, 50)``
...
... """)

>>> from tl.testing.cairo import DocFileSuite
>>> run(DocFileSuite(sample_txt, globs={'create_surface': create_surface}))
<SET UP>
  Ran 1 tests with 0 failures and 0 errors in 0.024 seconds.
<TEAR DOWN>

On the other hand, canonicalisation must not be overzealous: different images
still have to yield a mismatch:

>>> def create_surface(x1, y1, x2, y2):
...     surface = cairo.ImageSurface(cairo.FORMAT_RGB24, 100, 100)
...     ctx = cairo.Context(surface)
...     ctx.rectangle(0, 0, 100, 100)
...     ctx.move_to(y1, x1)
...     ctx.line_to(y2, x2)
...     ctx.stroke()
...     return surface

>>> run(DocFileSuite(sample_txt, globs={'create_surface': create_surface}))
<SET UP>
Failure in test /tmp/tmpiyZVMs-test_dir/sample.txt
----------------------------------------------------------------------
File "/test_dir/sample.txt", line 1, in sample.txt:
Failed example:
    create_surface(25, 50, 75, 50)
Image differs from expectation: rgb24.png
  Ran 1 tests with 1 failures and 0 errors in 0.023 seconds.
<TEAR DOWN>


Matching multi-line figure captions
-----------------------------------

The way both regular expressions and Python code are employed to match figures
which are to be evaluated as graphical doc-tests is complex enough to deserve
some tests of its own.

A caption must contain exactly one pair of double back-ticks in order for the
Python expression to be determined unambiguously:

>>> sample_txt = write('sample.txt', """\
...
... .. figure:: rgb24.png
...
...     some text ``create_surface(25, 50, 75, 50) some more text
...
... """)
>>> run(DocFileSuite(sample_txt, globs={'create_surface': create_surface}))
<SET UP>...
  Ran 0 tests ...

>>> sample_txt = write('sample.txt', """\
...
... .. figure:: rgb24.png
...
...     some text ``create_surface(25, 50, 75, 50)`` some ``more`` text
...
... """)
>>> run(DocFileSuite(sample_txt, globs={'create_surface': create_surface}))
<SET UP>...
  Ran 0 tests ...

Multi-line captions should be recognized by being limited by whitespace-only
lines and the Python expression may be spread across several lines. In the
following example, we see that the caption doesn't include the last text line
by the fact that the additional double back-ticks don't get us into trouble:

>>> sample_txt = write('sample.txt', """\
...
... .. figure:: rgb24.png
...
...  
...     some text ``create_surface(25,
...      50, 75, 50)`` some more text
...     
...     text that doesn't belong to ``the`` caption
...
... """)
>>> run(DocFileSuite(sample_txt, globs={'create_surface': create_surface}))
<SET UP>...
  Ran 1 tests ...

Captions should also be completely recognized right at the end of the file:

>>> sample_txt = write('sample.txt', """\
...
... .. figure:: rgb24.png
...
...  
...     some text ``create_surface(25,
...      50, 75, 50)`` some more text
... """)
>>> run(DocFileSuite(sample_txt, globs={'create_surface': create_surface}))
<SET UP>...
  Ran 1 tests ...

Even the final newline character is not necessary:

>>> sample_txt = write('sample.txt', """\
...
... .. figure:: rgb24.png
...
...  
...     some text ``create_surface(25,
...      50, 75, 50)`` some more text""")
>>> run(DocFileSuite(sample_txt, globs={'create_surface': create_surface}))
<SET UP>...
  Ran 1 tests ...


Test options
============

If the options given in the caption of a graphical test cannot be evaluated,
the error reported contains the original traceback as well as the first line
number of the erroneous example:

>>> sample_txt = write('sample.txt', """\
...
... .. figure:: rgb24.png
...
...     ``create_surface(25, 50, 75, 50)`` # options: foo=bar
...
... """)
>>> run(DocFileSuite(sample_txt, globs={'create_surface': create_surface}))
<SET UP>
Error in test /test_dir/sample.txt
Traceback (most recent call last):
  ...
Exception: Options could not be evaluated in example at line 1:
    Traceback (most recent call last):
      ...
    NameError: name 'bar' is not defined
  Ran 1 tests with 0 failures and 1 errors in N.NNN seconds.
<TEAR DOWN>


.. Local Variables:
.. mode: rst
.. End:
