1 # -*- coding: utf-8 -*-
6 Configure py.test for support stuff.
8 :copyright: 2007 by Armin Ronacher, Alexander Schremmer.
9 :license: BSD, see LICENSE for more details.
14 sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
17 from jinja2 import Environment
18 from jinja2.loaders import BaseLoader
19 from jinja2.exceptions import TemplateNotFound
23 # This code adds support for coverage.py (see
24 # http://nedbatchelder.com/code/modules/coverage.html).
25 # It prints a coverage report for the modules specified in all
26 # module globals (of the test modules) named "coverage_modules".
28 import coverage, atexit
30 IGNORED_MODULES = ['jinja2._speedups', 'jinja2.defaults',
33 def report_coverage():
36 mod for name, mod in sys.modules.copy().iteritems() if
37 getattr(mod, '__file__', None) and
38 name.startswith('jinja2.') and
39 name not in IGNORED_MODULES
42 coverage.report(module_list)
44 def callback(option, opt_str, value, parser):
45 atexit.register(report_coverage)
49 py.test.config.addoptions('Test options', py.test.config.Option('-C',
50 '--coverage', action='callback', callback=callback,
51 help='Output information about code coverage (slow!)'))
57 class GlobalLoader(BaseLoader):
60 def get_source(self, environment, name):
62 return self.scope[name.upper() + 'TEMPLATE'], None, None
64 raise TemplateNotFound(name)
67 loader = GlobalLoader()
68 simple_env = Environment(trim_blocks=True, loader=loader, cache_size=0)
71 class Directory(py.test.collect.Directory):
74 rv = super(Directory, self).run()
75 if self.fspath.basename == 'tests':
80 if name == 'doctests':
81 return JinjaDocTestModule(name, parent=self)
82 return super(Directory, self).join(name)
85 class Module(py.test.collect.Module):
87 def __init__(self, *args, **kwargs):
89 super(Module, self).__init__(*args, **kwargs)
91 def makeitem(self, name, obj, usefilters=True):
92 if name.startswith('test_'):
93 if hasattr(obj, 'func_code'):
94 return JinjaTestFunction(name, parent=self)
95 elif isinstance(obj, basestring):
96 return JinjaDocTest(name, parent=self)
99 class JinjaTestFunction(py.test.collect.Function):
101 def execute(self, target, *args):
102 loader.scope = target.func_globals
103 co = target.func_code
104 if 'env' in co.co_varnames[:co.co_argcount]:
105 target(self.parent.env, *args)
110 class JinjaDocTest(py.test.collect.Item):
112 def __init__(self, *args, **kwargs):
113 realmod = kwargs.pop('realmod', False)
114 super(JinjaDocTest, self).__init__(*args, **kwargs)
115 self.realmod = realmod
119 mod = __import__(self.name, None, None, [''])
121 mod = py.std.types.ModuleType(self.name)
122 mod.__doc__ = self.obj
123 mod.env = self.parent.env
124 mod.MODULE = self.parent.obj
127 def execute(self, mod):
128 failed, tot = py.compat.doctest.testmod(mod, verbose=True)
130 py.test.fail('doctest %s: %s failed out of %s' % (
131 self.fspath, failed, tot))
134 class JinjaDocTestModule(py.test.collect.Module):
136 def __init__(self, *args, **kwargs):
137 super(JinjaDocTestModule, self).__init__(*args, **kwargs)
138 self.doctest_modules = [
139 'jinja2.environment', 'jinja2.compiler', 'jinja2.parser',
140 'jinja2.lexer', 'jinja2.ext', 'jinja2.sandbox',
141 'jinja2.filters', 'jinja2.tests', 'jinja2.utils',
146 return self.doctest_modules
148 def join(self, name):
149 return JinjaDocTest(name, parent=self, realmod=True)