comparison MoinMoin/conftest.py @ 4327:62177a952833

merged moin/1.8 repo (tests need more fixing)
author Thomas Waldmann <tw AT waldmann-edv DOT de>
date Tue, 23 Sep 2008 00:53:18 +0200
parents 07862b0663fd 8a1c8fb7c689
children f02b3e7dffe6
comparison
equal deleted inserted replaced
4326:07862b0663fd 4327:62177a952833
10 Tests that need the current request, for example to create a page 10 Tests that need the current request, for example to create a page
11 instance, can refer to self.request. It is injected into all test case 11 instance, can refer to self.request. It is injected into all test case
12 classes by the framework. 12 classes by the framework.
13 13
14 Tests that require a certain configuration, like section_numbers = 1, must 14 Tests that require a certain configuration, like section_numbers = 1, must
15 use a TestConfig to create the required configuration before the test. 15 use a Config class to define the required configuration within the test class.
16 Deleting the TestConfig instance will restore the previous configuration.
17 16
18 @copyright: 2005 Nir Soffer, 2007 Alexander Schremmer 17 @copyright: 2005 MoinMoin:NirSoffer,
18 2007 MoinMoin:AlexanderSchremmer,
19 2008 MoinMoin:ThomasWaldmann
19 @license: GNU GPL, see COPYING for details. 20 @license: GNU GPL, see COPYING for details.
20 """ 21 """
21 22
22 import atexit 23 import atexit
23 from sys import modules
24 import sys 24 import sys
25 25
26 import py 26 import py
27 27
28 rootdir = py.magic.autopath().dirpath() 28 rootdir = py.magic.autopath().dirpath()
29 moindir = rootdir.join("..") 29 moindir = rootdir.join("..")
30
31 sys.path.insert(0, str(moindir)) 30 sys.path.insert(0, str(moindir))
32 from MoinMoin._tests import maketestwiki, compat
33 modules["unittest"] = compat # evil hack
34
35 wikiconfig_dir = str(moindir.join("tests"))
36 31
37 from MoinMoin.support.python_compatibility import set 32 from MoinMoin.support.python_compatibility import set
38 from MoinMoin.web.request import TestRequest, Client 33 from MoinMoin.web.request import TestRequest, Client
39 from MoinMoin.wsgiapp import application, init 34 from MoinMoin.wsgiapp import application, init
35 from MoinMoin._tests import maketestwiki, wikiconfig
40 36
41 coverage_modules = set() 37 coverage_modules = set()
42
43 38
44 try: 39 try:
45 """ 40 """
46 This code adds support for coverage.py (see 41 This code adds support for coverage.py (see
47 http://nedbatchelder.com/code/modules/coverage.html). 42 http://nedbatchelder.com/code/modules/coverage.html).
51 46
52 import coverage 47 import coverage
53 48
54 def report_coverage(): 49 def report_coverage():
55 coverage.stop() 50 coverage.stop()
56 module_list = [modules[mod] for mod in coverage_modules] 51 module_list = [sys.modules[mod] for mod in coverage_modules]
57 module_list.sort() 52 module_list.sort()
58 coverage.report(module_list) 53 coverage.report(module_list)
59 54
60 def callback(option, opt_str, value, parser): 55 def callback(option, opt_str, value, parser):
61 atexit.register(report_coverage) 56 atexit.register(report_coverage)
68 63
69 except ImportError: 64 except ImportError:
70 coverage = None 65 coverage = None
71 66
72 67
73 def init_test_request(static_state=[False]): 68 def init_test_request(given_config=None, static_state=[False]):
74 if not static_state[0]: 69 if not static_state[0]:
75 maketestwiki.run(True) 70 maketestwiki.run(True)
76 static_state[0] = True 71 static_state[0] = True
77 if sys.path[0] != wikiconfig_dir:
78 sys.path.insert(0, wikiconfig_dir) # this is a race with py.test's collectors
79 # because they modify sys.path as well
80 request = TestRequest() 72 request = TestRequest()
73 request.given_config = given_config
81 request = init(request) 74 request = init(request)
82 return request 75 return request
83
84 class TestConfig:
85 """ Custom configuration for unit tests
86
87 Some tests assume a specific configuration, and will fail if the wiki admin
88 changed the configuration. For example, DateTime macro test assume
89 the default datetime_fmt.
90
91 When you set custom values in a TestConfig, the previous values are saved,
92 and when the TestConfig is called specifically, they are restored automatically.
93
94 Typical Usage
95 -------------
96 ::
97 class SomeTest:
98 def setUp(self):
99 self.config = self.TestConfig(defaults=key_list, key=value,...)
100 def tearDown(self):
101 self.config.restore()
102 def testSomething(self):
103 # test that needs those defaults and custom values
104 """
105
106 def __init__(self, request):
107 """ Create temporary configuration for a test
108
109 @param request: current request
110 """
111 self.request = request
112 self.old = {} # Old config values
113 self.new = [] # New added attributes
114
115 def __call__(self, defaults=(), **custom):
116 """ Initialise a temporary configuration for a test
117
118 @param defaults: list of keys that should use the default value
119 @param custom: other keys using non default values, or new keys
120 that request.cfg does not have already
121 """
122 self.setDefaults(defaults)
123 self.setCustom(**custom)
124
125 return self
126
127 def setDefaults(self, defaults=()):
128 """ Set default values for keys in defaults list
129
130 Non existing default will raise an AttributeError.
131 """
132 from MoinMoin.config import multiconfig
133 for key in defaults:
134 self._setattr(key, getattr(multiconfig.DefaultConfig, key))
135
136 def setCustom(self, **custom):
137 """ Set custom values """
138 for key, value in custom.items():
139 self._setattr(key, value)
140
141 def _setattr(self, key, value):
142 """ Set a new value for key saving new added keys """
143 if hasattr(self.request.cfg, key):
144 self.old[key] = getattr(self.request.cfg, key)
145 else:
146 self.new.append(key)
147 setattr(self.request.cfg, key, value)
148
149 def restore(self):
150 """ Restore previous request.cfg
151
152 Set old keys to old values and delete new keys.
153 """
154 for key, value in self.old.items():
155 setattr(self.request.cfg, key, value)
156 for key in self.new:
157 delattr(self.request.cfg, key)
158 __del__ = restore # XXX __del__ semantics are currently broken
159
160 76
161 77
162 # py.test customization starts here 78 # py.test customization starts here
163 79
164 class MoinTestFunction(py.test.collect.Function): 80 class MoinTestFunction(py.test.collect.Function):
174 class MoinClassCollector(py.test.collect.Class): 90 class MoinClassCollector(py.test.collect.Class):
175 Function = MoinTestFunction 91 Function = MoinTestFunction
176 92
177 def setup(self): 93 def setup(self):
178 cls = self.obj 94 cls = self.obj
179 cls.request = self.parent.request 95 if hasattr(cls, 'Config'):
180 cls.TestConfig = TestConfig(cls.request) 96 cls.request = init_test_request(given_config=cls.Config)
97 else:
98 cls.request = self.parent.request
181 cls.client = Client(application) 99 cls.client = Client(application)
182 super(MoinClassCollector, self).setup() 100 super(MoinClassCollector, self).setup()
183 101
184 102
185 class Module(py.test.collect.Module): 103 class Module(py.test.collect.Module):
186 Class = MoinClassCollector 104 Class = MoinClassCollector
187 Function = MoinTestFunction 105 Function = MoinTestFunction
188 106
189 def __init__(self, *args, **kwargs): 107 def __init__(self, *args, **kwargs):
190 self.request = init_test_request() 108 self.request = init_test_request(given_config=wikiconfig.Config)
191 super(Module, self).__init__(*args, **kwargs) 109 super(Module, self).__init__(*args, **kwargs)
192 110
193 def run(self, *args, **kwargs): 111 def run(self, *args, **kwargs):
194 if coverage is not None: 112 if coverage is not None:
195 coverage_modules.update(getattr(self.obj, 'coverage_modules', [])) 113 coverage_modules.update(getattr(self.obj, 'coverage_modules', []))