1 """Tests for the CherryPy configuration system."""
2
3 import os
4 import sys
5 import unittest
6
7 import cherrypy
8 import cherrypy._cpcompat as compat
9
10 localDir = os.path.join(os.getcwd(), os.path.dirname(__file__))
11
12
22
23 def db_namespace(self, k, v):
24 if k == "scheme":
25 self.db = v
26
27
28 def index(self, key):
29 return cherrypy.request.config.get(key, "None")
30 index = cherrypy.expose(index, alias=('global_', 'xyz'))
31
32 def repr(self, key):
33 return repr(cherrypy.request.config.get(key, None))
34 repr.exposed = True
35
36 def dbscheme(self):
37 return self.db
38 dbscheme.exposed = True
39
40 def plain(self, x):
41 return x
42 plain.exposed = True
43 plain._cp_config = {'request.body.attempt_charsets': ['utf-16']}
44
45 favicon_ico = cherrypy.tools.staticfile.handler(
46 filename=os.path.join(localDir, '../favicon.ico'))
47
48 class Foo:
49
50 _cp_config = {'foo': 'this2',
51 'baz': 'that2'}
52
53 def index(self, key):
54 return cherrypy.request.config.get(key, "None")
55 index.exposed = True
56 nex = index
57
58 def silly(self):
59 return 'Hello world'
60 silly.exposed = True
61 silly._cp_config = {'response.headers.X-silly': 'sillyval'}
62
63
64
65
66 def bar(self, key):
67 return repr(cherrypy.request.config.get(key, None))
68 bar.exposed = True
69 bar._cp_config = {'foo': 'this3', 'bax': 'this4'}
70
71 class Another:
72
73 def index(self, key):
74 return str(cherrypy.request.config.get(key, "None"))
75 index.exposed = True
76
77 def raw_namespace(key, value):
78 if key == 'input.map':
79 handler = cherrypy.request.handler
80
81 def wrapper():
82 params = cherrypy.request.params
83 for name, coercer in list(value.items()):
84 try:
85 params[name] = coercer(params[name])
86 except KeyError:
87 pass
88 return handler()
89 cherrypy.request.handler = wrapper
90 elif key == 'output':
91 handler = cherrypy.request.handler
92
93 def wrapper():
94
95 return value(handler())
96 cherrypy.request.handler = wrapper
97
98 class Raw:
99
100 _cp_config = {'raw.output': repr}
101
102 def incr(self, num):
103 return num + 1
104 incr.exposed = True
105 incr._cp_config = {'raw.input.map': {'num': int}}
106
107 if not compat.py3k:
108 thing3 = "thing3: unicode('test', errors='ignore')"
109 else:
110 thing3 = ''
111
112 ioconf = compat.StringIO("""
113 [/]
114 neg: -1234
115 filename: os.path.join(sys.prefix, "hello.py")
116 thing1: cherrypy.lib.httputil.response_codes[404]
117 thing2: __import__('cherrypy.tutorial', globals(), locals(), ['']).thing2
118 %s
119 complex: 3+2j
120 mul: 6*3
121 ones: "11"
122 twos: "22"
123 stradd: %%(ones)s + %%(twos)s + "33"
124
125 [/favicon.ico]
126 tools.staticfile.filename = %r
127 """ % (thing3, os.path.join(localDir, 'static/dirback.jpg')))
128
129 root = Root()
130 root.foo = Foo()
131 root.raw = Raw()
132 app = cherrypy.tree.mount(root, config=ioconf)
133 app.request_class.namespaces['raw'] = raw_namespace
134
135 cherrypy.tree.mount(Another(), "/another")
136 cherrypy.config.update({'luxuryyacht': 'throatwobblermangrove',
137 'db.scheme': r"sqlite///memory",
138 })
139
140
141
142
143 from cherrypy.test import helper
144
145
147 setup_server = staticmethod(setup_server)
148
150 tests = [
151 ('/', 'nex', 'None'),
152 ('/', 'foo', 'this'),
153 ('/', 'bar', 'that'),
154 ('/xyz', 'foo', 'this'),
155 ('/foo/', 'foo', 'this2'),
156 ('/foo/', 'bar', 'that'),
157 ('/foo/', 'bax', 'None'),
158 ('/foo/bar', 'baz', "'that2'"),
159 ('/foo/nex', 'baz', 'that2'),
160
161
162 ('/another/', 'foo', 'None'),
163 ]
164 for path, key, expected in tests:
165 self.getPage(path + "?key=" + key)
166 self.assertBody(expected)
167
168 expectedconf = {
169
170 'tools.log_headers.on': False,
171 'tools.log_tracebacks.on': True,
172 'request.show_tracebacks': True,
173 'log.screen': False,
174 'environment': 'test_suite',
175 'engine.autoreload.on': False,
176
177 'luxuryyacht': 'throatwobblermangrove',
178
179 'bar': 'that',
180
181 'baz': 'that2',
182
183 'foo': 'this3',
184 'bax': 'this4',
185 }
186 for key, expected in expectedconf.items():
187 self.getPage("/foo/bar?key=" + key)
188 self.assertBody(repr(expected))
189
219
224
231
239
241 self.getPage("/plain", method='POST', headers=[
242 ('Content-Type', 'application/x-www-form-urlencoded'),
243 ('Content-Length', '13')],
244 body=compat.ntob('\xff\xfex\x00=\xff\xfea\x00b\x00c\x00'))
245 self.assertBody("abc")
246
247
249 setup_server = staticmethod(setup_server)
250
252 from textwrap import dedent
253
254
255 conf = dedent("""
256 [DEFAULT]
257 dir = "/some/dir"
258 my.dir = %(dir)s + "/sub"
259
260 [my]
261 my.dir = %(dir)s + "/my/dir"
262 my.dir2 = %(my.dir)s + '/dir2'
263
264 """)
265
266 fp = compat.StringIO(conf)
267
268 cherrypy.config.update(fp)
269 self.assertEqual(cherrypy.config["my"]["my.dir"], "/some/dir/my/dir")
270 self.assertEqual(cherrypy.config["my"]
271 ["my.dir2"], "/some/dir/my/dir/dir2")
272