1# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- 2# vi: set ft=python sts=4 ts=4 sw=4 et: 3""" 4Decorators for dipy tests 5""" 6 7import re 8import os 9import platform 10 11 12SKIP_RE = re.compile("(\s*>>>.*?)(\s*)#\s*skip\s+if\s+(.*)$") 13 14 15def doctest_skip_parser(func): 16 """Decorator replaces custom skip test markup in doctests. 17 18 Say a function has a docstring:: 19 20 >>> something # skip if not HAVE_AMODULE 21 >>> something + else 22 >>> something # skip if HAVE_BMODULE 23 24 This decorator will evaluate the expresssion after ``skip if``. If this 25 evaluates to True, then the comment is replaced by ``# doctest: +SKIP``. 26 If False, then the comment is just removed. The expression is evaluated in 27 the ``globals`` scope of `func`. 28 29 For example, if the module global ``HAVE_AMODULE`` is False, and module 30 global ``HAVE_BMODULE`` is False, the returned function will have 31 docstring:: 32 >>> something # doctest: +SKIP 33 >>> something + else 34 >>> something 35 36 """ 37 lines = func.__doc__.split('\n') 38 new_lines = [] 39 for line in lines: 40 match = SKIP_RE.match(line) 41 if match is None: 42 new_lines.append(line) 43 continue 44 code, space, expr = match.groups() 45 if eval(expr, func.__globals__): 46 code = code + space + "# doctest: +SKIP" 47 new_lines.append(code) 48 func.__doc__ = "\n".join(new_lines) 49 return func 50 51### 52# In some cases (e.g., on Travis), we want to use a virtual frame-buffer for 53# testing. The following decorator runs the tests under xvfb (mediated by 54# xvfbwrapper) conditioned on an environment variable (that we set in 55# .travis.yml for these cases): 56use_xvfb = os.environ.get('TEST_WITH_XVFB', False) 57is_windows = platform.system().lower() == "windows" 58 59 60def xvfb_it(my_test): 61 """Run a test with xvfbwrapper.""" 62 # When we use verbose testing we want the name: 63 fname = my_test.__name__ 64 65 def test_with_xvfb(*args, **kwargs): 66 if use_xvfb: 67 from xvfbwrapper import Xvfb 68 display = Xvfb(width=1920, height=1080) 69 display.start() 70 my_test(*args, **kwargs) 71 if use_xvfb: 72 display.stop() 73 # Plant it back in and return the new function: 74 test_with_xvfb.__name__ = fname 75 return test_with_xvfb if not is_windows else my_test 76