sphinx / tests / util.py

georg.brandl cbc5331 




Georg Brandl 3a0071d 
Georg Brandl 4da052f 
georg.brandl cbc5331 




georg.brandl 7187a9f 
DasIch 1165d65 
DasIch 190be39 
georg.brandl 7187a9f 
gbrandl f2678b1 




georg.brandl cbc5331 
Georg Brandl f3f3074 
Georg Brandl 77cd4b7 
georg.brandl cbc5331 


Georg Brandl 6aa428b 
georg.brandl 7187a9f 
georg.brandl cbc5331 

Georg Brandl 4dd56e9 

Georg Brandl 1f19724 
georg.brandl de96e31 
DasIch 1165d65 
georg.brandl cbc5331 


georg.brandl 5ddec89 


georg.brandl cbc5331 

























georg.brandl 72370f1 
georg.brandl cbc5331 



Georg Brandl 6aa428b 














Georg Brandl 4dd56e9 








georg.brandl cbc5331 
georg.brandl 7bc9879 




georg.brandl 7187a9f 
georg.brandl cbc5331 
georg.brandl 7187a9f 
georg.brandl cbc5331 


georg.brandl 7187a9f 



georg.brandl cbc5331 

georg.brandl 7187a9f 
georg.brandl cbc5331 








Georg Brandl def6a37 
Georg Brandl 25e024b 


georg.brandl cbc5331 


Georg Brandl dd18222 
georg.brandl 0a71b9b 
georg.brandl cbc5331 
georg.brandl 5ddec89 
georg.brandl 7187a9f 
georg.brandl 0a71b9b 




georg.brandl cbc5331 

georg.brandl 7187a9f 
georg.brandl cbc5331 


georg.brandl 7187a9f 


georg.brandl 0a71b9b 
georg.brandl cbc5331 
georg.brandl 7187a9f 
georg.brandl 0a71b9b 

georg.brandl cbc5331 




georg.brandl 7187a9f 
georg.brandl cbc5331 
georg.brandl 0a71b9b 
Georg Brandl 25e024b 

georg.brandl cbc5331 


Georg Brandl 25e024b 
georg.brandl cbc5331 
georg.brandl 0a71b9b 
Georg Brandl 77cd4b7 
georg.brandl 0a71b9b 
georg.brandl e63649e 
georg.brandl 7187a9f 

georg.brandl 72370f1 
georg.brandl 7187a9f 







Georg Brandl 4b4bd9d 


Georg Brandl 1f19724 





Georg Brandl 89bfbde 

Georg Brandl 1f19724 




Georg Brandl 4b4bd9d 



georg.brandl 7187a9f 


georg.brandl cbc5331 

Georg Brandl d0113d9 
georg.brandl cbc5331 
Georg Brandl d0113d9 
georg.brandl cbc5331 




DasIch 190be39 






Georg Brandl 89bfbde 
georg.brandl cbc5331 

georg.brandl 7187a9f 



DasIch 1165d65 
Georg Brandl 7d6ffc3 
DasIch 1165d65 
# -*- coding: utf-8 -*-
"""
    Sphinx test suite utilities
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~

    :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
    :license: BSD, see LICENSE for details.
"""

import sys
import StringIO
import tempfile
import shutil
import re
from codecs import open

try:
    from functools import wraps
except ImportError:
    # functools is new in 2.4
    wraps = lambda f: (lambda w: w)

from sphinx import application
from sphinx.ext.autodoc import AutoDirective

from path import path

from nose import tools, SkipTest


__all__ = [
    'test_root', 'raises', 'raises_msg',
    'skip_if', 'skip_unless', 'skip_unless_importable', 'Struct',
    'ListOutput', 'TestApp', 'with_app', 'gen_with_app',
    'path', 'with_tempdir', 'write_file',
    'sprint', 'remove_unicode_literals',
]


test_root = path(__file__).parent.joinpath('root').abspath()


def _excstr(exc):
    if type(exc) is tuple:
        return str(tuple(map(_excstr, exc)))
    return exc.__name__

def raises(exc, func, *args, **kwds):
    """
    Raise :exc:`AssertionError` if ``func(*args, **kwds)`` does not
    raise *exc*.
    """
    try:
        func(*args, **kwds)
    except exc:
        pass
    else:
        raise AssertionError('%s did not raise %s' %
                             (func.__name__, _excstr(exc)))

def raises_msg(exc, msg, func, *args, **kwds):
    """
    Raise :exc:`AssertionError` if ``func(*args, **kwds)`` does not
    raise *exc*, and check if the message contains *msg*.
    """
    try:
        func(*args, **kwds)
    except exc, err:
        assert msg in str(err), "\"%s\" not in \"%s\"" % (msg, err)
    else:
        raise AssertionError('%s did not raise %s' %
                             (func.__name__, _excstr(exc)))

def skip_if(condition, msg=None):
    """Decorator to skip test if condition is true."""
    def deco(test):
        @tools.make_decorator(test)
        def skipper(*args, **kwds):
            if condition:
                raise SkipTest(msg or 'conditional skip')
            return test(*args, **kwds)
        return skipper
    return deco

def skip_unless(condition, msg=None):
    """Decorator to skip test if condition is false."""
    return skip_if(not condition, msg)

def skip_unless_importable(module, msg=None):
    """Decorator to skip test if module is not importable."""
    try:
        __import__(module)
    except ImportError:
        return skip_if(True, msg)
    else:
        return skip_if(False, msg)


class Struct(object):
    def __init__(self, **kwds):
        self.__dict__.update(kwds)


class ListOutput(object):
    """
    File-like object that collects written text in a list.
    """
    def __init__(self, name):
        self.name = name
        self.content = []

    def reset(self):
        del self.content[:]

    def write(self, text):
        self.content.append(text)


class TestApp(application.Sphinx):
    """
    A subclass of :class:`Sphinx` that runs on the test root, with some
    better default values for the initialization parameters.
    """

    def __init__(self, srcdir=None, confdir=None, outdir=None, doctreedir=None,
                 buildername='html', confoverrides=None,
                 status=None, warning=None, freshenv=None,
                 warningiserror=None, tags=None,
                 confname='conf.py', cleanenv=False):

        application.CONFIG_FILENAME = confname

        self.cleanup_trees = [test_root / 'generated']

        if srcdir is None:
            srcdir = test_root
        if srcdir == '(temp)':
            tempdir = path(tempfile.mkdtemp())
            self.cleanup_trees.append(tempdir)
            temproot = tempdir / 'root'
            test_root.copytree(temproot)
            srcdir = temproot
        else:
            srcdir = path(srcdir)
        self.builddir = srcdir.joinpath('_build')
        if confdir is None:
            confdir = srcdir
        if outdir is None:
            outdir = srcdir.joinpath(self.builddir, buildername)
            if not outdir.isdir():
                outdir.makedirs()
            self.cleanup_trees.insert(0, outdir)
        if doctreedir is None:
            doctreedir = srcdir.joinpath(srcdir, self.builddir, 'doctrees')
            if cleanenv:
                self.cleanup_trees.insert(0, doctreedir)
        if confoverrides is None:
            confoverrides = {}
        if status is None:
            status = StringIO.StringIO()
        if warning is None:
            warning = ListOutput('stderr')
        if freshenv is None:
            freshenv = False
        if warningiserror is None:
            warningiserror = False

        application.Sphinx.__init__(self, srcdir, confdir, outdir, doctreedir,
                                    buildername, confoverrides, status, warning,
                                    freshenv, warningiserror, tags)

    def cleanup(self, doctrees=False):
        AutoDirective._registry.clear()
        for tree in self.cleanup_trees:
            shutil.rmtree(tree, True)


def with_app(*args, **kwargs):
    """
    Make a TestApp with args and kwargs, pass it to the test and clean up
    properly.
    """
    def generator(func):
        @wraps(func)
        def deco(*args2, **kwargs2):
            app = TestApp(*args, **kwargs)
            func(app, *args2, **kwargs2)
            # don't execute cleanup if test failed
            app.cleanup()
        return deco
    return generator


def gen_with_app(*args, **kwargs):
    """
    Decorate a test generator to pass a TestApp as the first argument to the
    test generator when it's executed.
    """
    def generator(func):
        @wraps(func)
        def deco(*args2, **kwargs2):
            app = TestApp(*args, **kwargs)
            for item in func(app, *args2, **kwargs2):
                yield item
            # don't execute cleanup if test failed
            app.cleanup()
        return deco
    return generator


def with_tempdir(func):
    def new_func(*args, **kwds):
        tempdir = path(tempfile.mkdtemp())
        func(tempdir, *args, **kwds)
        tempdir.rmtree()
    new_func.__name__ = func.__name__
    return new_func


def write_file(name, contents, encoding=None):
    if encoding is None:
        mode = 'wb'
        if isinstance(contents, unicode):
            contents = contents.encode('ascii')
    else:
        mode = 'w'
    f = open(str(name), mode, encoding=encoding)
    f.write(contents)
    f.close()


def sprint(*args):
    sys.stderr.write(' '.join(map(str, args)) + '\n')

_unicode_literals_re = re.compile(r'u(".*?")|u(\'.*?\')')
def remove_unicode_literals(s):
    return _unicode_literals_re.sub(lambda x: x.group(1) or x.group(2), s)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.