blob: 0c5a5fff9399d37ac4477f7b75ac7cf678bd1579 [file] [log] [blame]
Armin Ronacherab45b842007-03-18 20:47:50 +01001# -*- coding: utf-8 -*-
2"""
3 conftest
4 ~~~~~~~~
5
6 Configure py.test for support stuff.
7
8 :copyright: 2007 by Armin Ronacher, Alexander Schremmer.
9 :license: BSD, see LICENSE for more details.
10"""
11
12import os
13import sys
14sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
15
16import py
Armin Ronacherab45b842007-03-18 20:47:50 +010017from jinja import Environment
Armin Ronacherc1e30402007-03-18 22:41:09 +010018from jinja.parser import Parser
Armin Ronacherab45b842007-03-18 20:47:50 +010019
Armin Ronacherccf284b2007-05-21 16:44:26 +020020try:
21 # This code adds support for coverage.py (see
22 # http://nedbatchelder.com/code/modules/coverage.html).
23 # It prints a coverage report for the modules specified in all
24 # module globals (of the test modules) named "coverage_modules".
25
26 import coverage, atexit
27
28 IGNORED_MODULES = ['jinja._speedups', 'jinja.defaults',
29 'jinja.translators']
30
31 def report_coverage():
32 coverage.stop()
33 module_list = [
34 mod for name, mod in sys.modules.copy().iteritems() if
35 getattr(mod, '__file__', None) and
36 name.startswith('jinja.') and
37 name not in IGNORED_MODULES
38 ]
39 module_list.sort()
40 coverage.report(module_list)
41
42 def callback(option, opt_str, value, parser):
43 atexit.register(report_coverage)
44 coverage.erase()
45 coverage.start()
46
47 py.test.config.addoptions('Test options', py.test.config.Option('-C',
48 '--coverage', action='callback', callback=callback,
49 help='Output information about code coverage (slow!)'))
50
51except ImportError:
52 coverage = None
53
Armin Ronacherab45b842007-03-18 20:47:50 +010054
Armin Ronacherc1e30402007-03-18 22:41:09 +010055class GlobalLoader(object):
56
57 def __init__(self, scope):
58 self.scope = scope
59
60 def get_source(self, environment, name, parent, scope=None):
61 return self.scope[name.upper() + 'TEMPLATE']
62
63 def parse(self, environment, name, parent, scope=None):
64 return Parser(environment, self.get_source(environment, name,
65 parent, scope), name).parse()
66
67 def load(self, environment, name, translator, scope=None):
68 return translator.process(environment, self.parse(environment,
69 name, None, scope))
70
71
72loader = GlobalLoader(globals())
Armin Ronacheree2c18e2007-04-20 22:39:04 +020073simple_env = Environment(trim_blocks=True, friendly_traceback=False, loader=loader)
Armin Ronacherab45b842007-03-18 20:47:50 +010074
75
Armin Ronacher143a07e2007-06-02 01:47:34 +020076class MemcacheClient(object):
77 """
78 Helper for the loader test.
79 """
80
81 def __init__(self, hosts):
82 self.cache = {}
83
84 def get(self, name):
85 return self.cache.get(name)
86
87 def set(self, name, data, time):
88 self.cache[name] = data
89
90sys.modules['memcache'] = memcache = type(sys)('memcache')
91memcache.Client = MemcacheClient
92
93
Armin Ronacherab45b842007-03-18 20:47:50 +010094class Module(py.test.collect.Module):
95
96 def __init__(self, *args, **kwargs):
97 self.env = simple_env
98 super(Module, self).__init__(*args, **kwargs)
99
Armin Ronacherccf284b2007-05-21 16:44:26 +0200100 def makeitem(self, name, obj, usefilters=True):
101 if name.startswith('test_'):
102 if hasattr(obj, 'func_code'):
103 return JinjaTestFunction(name, parent=self)
104 elif isinstance(obj, basestring):
105 return JinjaDocTest(name, parent=self)
Armin Ronacherab45b842007-03-18 20:47:50 +0100106
107
108class JinjaTestFunction(py.test.collect.Function):
109
110 def execute(self, target, *args):
Armin Ronacherc1e30402007-03-18 22:41:09 +0100111 loader.scope = target.func_globals
Armin Ronacherab45b842007-03-18 20:47:50 +0100112 co = target.func_code
113 if 'env' in co.co_varnames[:co.co_argcount]:
114 target(self.parent.env, *args)
115 else:
116 target(*args)
Armin Ronacherccf284b2007-05-21 16:44:26 +0200117
118
119class JinjaDocTest(py.test.collect.Item):
120
121 def run(self):
122 mod = py.std.types.ModuleType(self.name)
123 mod.__doc__ = self.obj
124 self.execute(mod)
125
126 def execute(self, mod):
127 mod.env = self.parent.env
128 mod.MODULE = self.parent.obj
129 failed, tot = py.compat.doctest.testmod(mod, verbose=True)
130 if failed:
131 py.test.fail('doctest %s: %s failed out of %s' % (
132 self.fspath, failed, tot))