git.fiddlerwoaroof.com
Browse code

Bugfixes: the server tests did not pass

Also, added a 'methods' object to the eventhandler... this can be used
instead of "findmethod" it should be an object defining a 'get' method
which takes a name and returns the method to be called

Ed L authored on 21/12/2011 20:16:12
Showing 2 changed files
... ...
@@ -30,6 +30,7 @@
30 30
 #  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 31
 #
32 32
 #
33
+import traceback
33 34
 import jsonrpc.jsonutil
34 35
 from jsonrpc.utilities import public
35 36
 import jsonrpc.common
... ...
@@ -40,6 +41,7 @@ from twisted.internet import threads
40 41
 from twisted.internet import defer
41 42
 from twisted.web.resource import Resource
42 43
 
44
+import abc
43 45
 
44 46
 import copy
45 47
 import UserDict, collections
... ...
@@ -49,6 +51,11 @@ collections.Mapping.register(UserDict.DictMixin)
49 51
 class ServerEvents(object):
50 52
 	'''Subclass this and pass to :py:meth:`JSON_RPC.customize` to customize the JSON-RPC server'''
51 53
 
54
+	DEBUG = False
55
+
56
+	#: an object defining a 'get' method which contains the methods
57
+	methods = None
58
+
52 59
 	def __init__(self, server):
53 60
 		#: A link to the JSON-RPC server instance
54 61
 		self.server = server
... ...
@@ -57,17 +64,35 @@ class ServerEvents(object):
57 64
 		'''Find the method and call it with the specified args
58 65
 
59 66
 		:returns: the result of the method'''
60
-		method = self.findmethod(rpcrequest.method)
61
-		if method is None: raise jsonrpc.common.MethodNotFound
67
+
62 68
 		extra.update(rpcrequest.kwargs)
63 69
 
64
-		return method(*rpcrequest.args, **extra)
70
+		method, postprocess_result = self.findmethod(rpcrequest.method, rpcrequest.args, extra), False
71
+		if hasattr('method', '__iter__'):
72
+			method, postprocess_result = method
73
+
74
+		if self.DEBUG:
75
+			# Debugging: raise AssertionError if type of method is invalid
76
+			assert method is None or callable(method), 'the returned method is not callable'
77
+
78
+		if not callable(method): raise jsonrpc.common.MethodNotFound
79
+
80
+		result = method(*rpcrequest.args, **extra)
81
+
82
+		#if the result needs to be adjusted/validated, do it
83
+		if postprocess_result:
84
+			result = self.methods.postprocess(rpcrequest.method, result, rpcrequest.args, extra)
85
+
86
+		return result
65 87
 
66
-	def findmethod(self, method_name):
88
+	def findmethod(self, method_name, args=None, kwargs=None):
67 89
 		'''Return the callable associated with the method name
68 90
 
69
-		:returns: a callable'''
70
-		raise NotImplementedError
91
+		:returns: a callable or None if the method is not found'''
92
+		if self.methods is not None:
93
+			return self.methods.get_method(method_name)
94
+		else:
95
+			raise NotImplementedError
71 96
 
72 97
 	def processrequest(self, result, args, **kw):
73 98
 		'''Override to implement custom handling of the method result and request'''
... ...
@@ -91,11 +116,11 @@ class ServerEvents(object):
91 116
 		for example
92 117
 
93 118
 			def getresponsecode(self, result):
94
-		  		code = 200
95
-		  		if not isinstance(result, list):
96
-		  			if result is not None and result.error is not None:
97
-		  				code = result.error.code or 500
98
-		  		return code
119
+				code = 200
120
+				if not isinstance(result, list):
121
+					if result is not None and result.error is not None:
122
+						code = result.error.code or 500
123
+				return code
99 124
 
100 125
 
101 126
 		:returns: :py:class:`int`'''
... ...
@@ -108,6 +133,19 @@ class ServerEvents(object):
108 133
 		:returns: :py:class:`twisted.internet.defer.Deferred`'''
109 134
 		return threads.deferToThread(method, *a, **kw)
110 135
 
136
+	def defer_with_rpcrequest(self, method, rpcrequest, *a, **kw):
137
+		d = threads.deferToThread(method, rpcrequest, *a, **kw)
138
+
139
+		@d.addCallback
140
+		def _inner(result):
141
+			return result, rpcrequest
142
+		@d.addErrback
143
+		def _inner(result):
144
+			result.rpcrequest = rpcrequest
145
+			return result
146
+
147
+		return d
148
+
111 149
 
112 150
 
113 151
 ## Base class providing a JSON-RPC 2.0 implementation with 2 customizable hooks
... ...
@@ -173,7 +211,7 @@ class JSON_RPC(Resource):
173 211
 
174 212
 		if contents == []: raise jsonrpc.common.InvalidRequest
175 213
 
176
-		def callmethod(request, rpcrequest, add, **kwargs):
214
+		def callmethod(rpcrequest, request, add, **kwargs):
177 215
 			add.update(kwargs)
178 216
 			result = self.eventhandler.callmethod(request, rpcrequest, **add)
179 217
 			return result
... ...
@@ -183,25 +221,31 @@ class JSON_RPC(Resource):
183 221
 			res = None
184 222
 			add = copy.deepcopy(rpcrequest.extra)
185 223
 			add.update(kw)
186
-			deferreds.append(self.eventhandler.defer(callmethod, request, rpcrequest, add))
224
+			deferreds.append(self.eventhandler.defer_with_rpcrequest(callmethod, rpcrequest, request, add))
187 225
 		deferreds = defer.DeferredList(deferreds, consumeErrors=True)
188 226
 
189 227
 		@deferreds.addCallback
190 228
 		def helper(deferredresults):
191 229
 			result = []
192
-			for success, methodresult in deferredresults:
193
-				res = None
194
-				if success:
195
-					res = jsonrpc.common.Response(id=rpcrequest.id, result=methodresult)
196
-					res = self.eventhandler.processrequest(res, request.args, **kw)
197
-				else:
198
-					try:
199
-						methodresult.raiseException()
200
-					except Exception, e:
201
-						res = self.render_error(e, rpcrequest.id)
202
-
203
-				if res.id is not None:
204
-					result.append(res)
230
+			try:
231
+				for success, methodresult in deferredresults:
232
+					res = None
233
+					if success:
234
+						methodresult, rpcrequest = methodresult
235
+						res = jsonrpc.common.Response(id=rpcrequest.id, result=methodresult)
236
+						res = self.eventhandler.processrequest(res, request.args, **kw)
237
+					else:
238
+						rpcrequest = methodresult.rpcrequest
239
+						try:
240
+							methodresult.raiseException()
241
+						except Exception, e:
242
+							res = self.render_error(e, rpcrequest.id)
243
+
244
+					if res.id is not None:
245
+						result.append(res)
246
+			except Exception, e:
247
+				traceback.print_exc()
248
+				raise
205 249
 
206 250
 			if result != []:
207 251
 				if not islist: result = result[0]
... ...
@@ -30,6 +30,7 @@
30 30
 #  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 31
 #
32 32
 #
33
+import functools
33 34
 from twisted.trial import unittest
34 35
 import StringIO
35 36
 
... ...
@@ -46,7 +47,7 @@ def _render(resource, request):
46 47
     result = resource.render(request)
47 48
     if isinstance(result, str):
48 49
         request.write(result)
49
-        request.finish()
50
+        equest.finish()
50 51
         return succeed(None)
51 52
     elif result is server.NOT_DONE_YET:
52 53
         if request.finished:
... ...
@@ -59,7 +60,7 @@ def _render(resource, request):
59 60
 class SimpleEventHandler(jsonrpc.server.ServerEvents):
60 61
 	def log(self, result, request, error=False): pass
61 62
 
62
-	def findmethod(self, method):
63
+	def findmethod(self, method, *_, **__):
63 64
 		if method in set(['echo', 'add']):
64 65
 			return getattr(self, method)
65 66
 
... ...
@@ -68,307 +69,269 @@ class SimpleEventHandler(jsonrpc.server.ServerEvents):
68 69
 
69 70
 	def echo(self, v): return v
70 71
 
72
+def TestResource(setup):
73
+	def _inner1(tests):
74
+		@functools.wraps(setup)
75
+		def _inner2(self):
76
+			resource = jsonrpc.server.JSON_RPC()
77
+			resource.customize(SimpleEventHandler)
71 78
 
72
-class TestJSONRPCServer(unittest.TestCase):
73
-
74
-	def setUp(self):
75
-		self.id_ = 'an_id'
76
-		self.param = "some data"
77
-
78
-	def test_eventhandler(self):
79
-		resource = jsonrpc.server.JSON_RPC()
80
-		resource.eventhandler = mock.Mock(jsonrpc.server.ServerEvents)
81
-		resource.eventhandler.findmethod.return_value = lambda *a, **b: 'test data'
82
-
83
-		rv = {"jsonrpc": "2.0", "params": [self.param], "method": "echo", "id": self.id_}
84
-		resource.eventhandler.processcontent.return_value = rv
85
-		resource.eventhandler.processrequest.return_value = rv
86
-
87
-		request = DummyRequest([''])
88
-		request.getCookie = mock.Mock()
89
-		request.content = StringIO.StringIO(jsonrpc.jsonutil.encode(rv))
90
-
91
-		d = _render(resource, request)
79
+			request = DummyRequest([''])
80
+			request.getCookie = mock.Mock()
92 81
 
93
-		@d.addCallback
94
-		def rendered(ignored):
95
-			self.assertTrue(resource.eventhandler.processcontent.called)
96
-			self.assertTrue(resource.eventhandler.callmethod.called)
97
-			self.assertTrue(resource.eventhandler.processrequest.called)
98
-			self.assertTrue(resource.eventhandler.log.called)
82
+			result = setup(self, request, resource)
83
+			if result is not None:
84
+				request, resource = result
99 85
 
100
-		return d
86
+			d = _render(resource, request).addCallback(tests, self, request, resource)
87
+			return d
88
+		return _inner2
89
+	return _inner1
101 90
 
102
-	def test_requestid(self):
103
-		resource = jsonrpc.server.JSON_RPC()
104
-		resource.customize(SimpleEventHandler)
105 91
 
106
-		request0 = DummyRequest([''])
107
-		request0.getCookie = mock.Mock()
108
-		request0.content = StringIO.StringIO('{"jsonrpc": "2.0", "params": %s, "method": "echo", "id": "%s"}' % (jsonrpc.jsonutil.encode([self.param]), self.id_))
109
-
110
-		d0 = _render(resource, request0)
111
-		@d0.addCallback
112
-		def rendered(ignored):
113
-			self.assertEqual(len(request0.written), 1)
114
-			data = jsonrpc.jsonutil.decode(request0.written[0])
92
+class TestJSONRPCServer(unittest.TestCase):
115 93
 
116
-			self.assertEqual(data["id"], self.id_)
94
+	def setUp(self):
95
+		self.id_ = 'an_id'
96
+		self.param = "some data"
117 97
 
98
+	@TestResource
99
+	def test_eventhandler(self, request, resource):
100
+		resource.eventhandler = mock.Mock(wraps=resource.eventhandler)
101
+		request.content = StringIO.StringIO('{"jsonrpc": "2.0", "params": %s, "method": "echo", "id": "%s"}' % (jsonrpc.jsonutil.encode([self.param]), self.id_))
102
+		return request, resource
103
+
104
+	@test_eventhandler
105
+	def test_eventhandler(ignored, self, request, resource):
106
+		self.assertTrue( resource.eventhandler.processcontent.called )
107
+		self.assertTrue( resource.eventhandler.defer_with_rpcrequest.called )
108
+		self.assertTrue( resource.eventhandler.callmethod.called )
109
+		self.assertTrue( resource.eventhandler.defer.called )
110
+		self.assertTrue( resource.eventhandler.getresponsecode.called )
111
+		self.assertTrue( resource.eventhandler.log.called )
112
+
113
+	@TestResource
114
+	def test_requestid0(self, request, resource):
115
+		request.content = StringIO.StringIO('{"jsonrpc": "2.0", "params": %s, "method": "echo", "id": "%s"}' % (jsonrpc.jsonutil.encode([self.param]), self.id_))
116
+		return request, resource
118 117
 
119
-		request1 = DummyRequest([''])
120
-		request1.getCookie = mock.Mock()
121
-		request1.content = StringIO.StringIO('{"jsonrpc": "2.0", "params": %s, "method": "echo", "id": 1}' % jsonrpc.jsonutil.encode([self.param]))
118
+	@test_requestid0
119
+	def test_requestid0(ignored, self, request, resource):
120
+		self.assertEqual(len(request.written), 1)
121
+		data = jsonrpc.jsonutil.decode(request.written[0])
122 122
 
123
-		d1 = _render(resource, request1)
124
-		@d1.addCallback
125
-		def rendered(ignored):
126
-			self.assertEqual(len(request1.written), 1)
127
-			data = jsonrpc.jsonutil.decode(request1.written[0])
123
+		self.assertEqual(data["id"], self.id_)
128 124
 
129
-			self.assertEqual(data["id"], 1)
130 125
 
126
+	@TestResource
127
+	def test_requestid1(self, request, resource):
128
+		request.content = StringIO.StringIO('{"jsonrpc": "2.0", "params": %s, "method": "echo", "id": 1}' % jsonrpc.jsonutil.encode([self.param]))
129
+		return request, resource
131 130
 
132
-		request3 = DummyRequest([''])
133
-		request3.getCookie = mock.Mock()
134
-		request3.content = StringIO.StringIO('{"jsonrpc": "2.0", "params": %s, "method": "echo", "id": []}' % jsonrpc.jsonutil.encode([self.param]))
131
+	@test_requestid1
132
+	def test_requestid1(ignored, self, request, resource):
133
+		self.assertEqual(len(request.written), 1)
134
+		data = jsonrpc.jsonutil.decode(request.written[0])
135 135
 
136
-		d3 = _render(resource, request3)
137
-		@d3.addCallback
138
-		def rendered(ignored):
139
-			self.assertEqual(len(request3.written), 1)
140
-			data = jsonrpc.jsonutil.decode(request3.written[0])
136
+		self.assertEqual(data["id"], 1)
141 137
 
142
-			self.assertNotEqual(data["id"], [])
143 138
 
144
-		request4 = DummyRequest([''])
145
-		request4.getCookie = mock.Mock()
146
-		request4.content = StringIO.StringIO('{"jsonrpc": "2.0", "params": %s, "method": "echo", "id": {}}' % jsonrpc.jsonutil.encode([self.param]))
139
+	@TestResource
140
+	def test_requestid2(self, request, resource):
141
+		request.content = StringIO.StringIO('{"jsonrpc": "2.0", "params": %s, "method": "echo", "id": []}' % jsonrpc.jsonutil.encode([self.param]))
142
+		return request, resource
147 143
 
148
-		d4 = _render(resource, request4)
149
-		@d4.addCallback
150
-		def rendered(ignored):
151
-			self.assertEqual(len(request4.written), 1)
152
-			data = jsonrpc.jsonutil.decode(request4.written[0])
144
+	@test_requestid2
145
+	def test_requestid2(ignored, self, request, resource):
146
+		self.assertEqual(len(request.written), 1)
147
+		data = jsonrpc.jsonutil.decode(request.written[0])
153 148
 
154
-			self.assertNotEqual(data["id"], {})
149
+		self.assertNotEqual(data["id"], [])
155 150
 
156
-		return DeferredList([d0,d1,d3,d4])
151
+	@TestResource
152
+	def test_requestid3(self, request, resource):
153
+		request.content = StringIO.StringIO('{"jsonrpc": "2.0", "params": %s, "method": "echo", "id": {}}' % jsonrpc.jsonutil.encode([self.param]))
154
+		return request, resource
157 155
 
156
+	@test_requestid3
157
+	def test_requestid3(ignored, self, request, resource):
158
+		self.assertEqual(len(request.written), 1)
159
+		data = jsonrpc.jsonutil.decode(request.written[0])
158 160
 
159
-	def test_invalid_data(self):
160
-		resource = jsonrpc.server.JSON_RPC()
161
-		resource.customize(SimpleEventHandler)
161
+		self.assertNotEqual(data["id"], {})
162 162
 
163
-		request = DummyRequest([''])
164
-		request.getCookie = mock.Mock()
163
+	@TestResource
164
+	def test_invalid_data(self, request, resource):
165 165
 		request.content = StringIO.StringIO(' {"v": %s}, "method": "echo"}' % (jsonrpc.jsonutil.encode(self.param)))
166
+		return request, resource
166 167
 
167
-		d = _render(resource, request)
168
-
169
-		@d.addCallback
170
-		def rendered(ignored):
171
-			self.assertEqual(len(request.written), 1)
172
-			data = jsonrpc.jsonutil.decode(request.written[0])
173
-
174
-			self.assertEqual(data, {"jsonrpc": "2.0", "error": {"code": -32700, "message": "Parse error."}, "id": None})
168
+	@test_invalid_data
169
+	def test_invalid_data(ignored, self, request, resource):
170
+		self.assertEqual(len(request.written), 1)
171
+		data = jsonrpc.jsonutil.decode(request.written[0])
175 172
 
176
-		return d
173
+		self.assertEqual(data, {"jsonrpc": "2.0", "error": {"code": -32700, "message": "Parse error."}, "id": None})
177 174
 
178
-	def test_wrongversion(self):
179
-		resource = jsonrpc.server.JSON_RPC()
180
-		resource.customize(SimpleEventHandler)
181 175
 
182
-		request = DummyRequest([''])
183
-		request.getCookie = mock.Mock()
176
+	@TestResource
177
+	def test_wrongversion(self, request, resource):
184 178
 		request.content = StringIO.StringIO('{"jsonrpc": "2.1", "params": %s, "method": "echo", "id": "%s"}' % (jsonrpc.jsonutil.encode([self.param]), self.id_))
185 179
 
186
-		d = _render(resource, request)
187 180
 
188
-		@d.addCallback
189
-		def rendered(ignored):
190
-			self.assertEqual(len(request.written), 1)
191
-			data = jsonrpc.jsonutil.decode(request.written[0])
192
-			self.assertEqual(data, {"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request."}, "id": self.id_})
193
-		return d
181
+	@test_wrongversion
182
+	def rendered(ignored, self, request, resource):
183
+		self.assertEqual(len(request.written), 1)
184
+		data = jsonrpc.jsonutil.decode(request.written[0])
185
+		self.assertEqual(data, {"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request."}, "id": self.id_})
194 186
 
195 187
 
196
-	def test_invalidmethodname(self):
197
-		resource = jsonrpc.server.JSON_RPC()
198
-		resource.customize(SimpleEventHandler)
199
-
200
-		request = DummyRequest([''])
201
-		request.getCookie = mock.Mock()
188
+	@TestResource
189
+	def test_invalidmethodname(self, request, resource):
202 190
 		request.content = StringIO.StringIO('{"jsonrpc": "2.0", "params": %s, "method": 0, "id": "%s"}' % (jsonrpc.jsonutil.encode([self.param]), self.id_))
203 191
 
204
-		d = _render(resource, request)
205
-
206
-		@d.addCallback
207
-		def rendered(ignored):
208
-			self.assertEqual(len(request.written), 1)
209
-			data = jsonrpc.jsonutil.decode(request.written[0])
210
-			self.assertEqual(data, {"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request."}, "id": self.id_})
211
-		return d
212 192
 
213
-	def test_missingmethod(self):
214
-		resource = jsonrpc.server.JSON_RPC()
215
-		resource.customize(SimpleEventHandler)
193
+	@test_invalidmethodname
194
+	def rendered(ignored, self, request, resource):
195
+		self.assertEqual(len(request.written), 1)
196
+		data = jsonrpc.jsonutil.decode(request.written[0])
197
+		self.assertEqual(data, {"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request."}, "id": self.id_})
216 198
 
217
-		request = DummyRequest([''])
218
-		request.getCookie = mock.Mock()
199
+	@TestResource
200
+	def test_missingmethod(self, request, resource):
219 201
 		request.content = StringIO.StringIO('{"jsonrpc": "2.0", "params": %s, "method": "non_existent", "id": "%s"}' % (jsonrpc.jsonutil.encode([self.param]), self.id_))
220 202
 
221
-		d = _render(resource, request)
222 203
 
223
-		@d.addCallback
224
-		def rendered(ignored):
225
-			self.assertEqual(len(request.written), 1)
226
-			data = jsonrpc.jsonutil.decode(request.written[0])
227
-			self.assertEqual(data, {"jsonrpc": "2.0", "error": {"code": -32601, "message": "Procedure not found."}, "id": self.id_})
228
-		return d
204
+	@test_missingmethod
205
+	def rendered(ignored, self, request, resource):
206
+		self.assertEqual(len(request.written), 1)
207
+		data = jsonrpc.jsonutil.decode(request.written[0])
208
+		self.assertEqual(data, {"jsonrpc": "2.0", "error": {"code": -32601, "message": "Procedure not found."}, "id": self.id_})
229 209
 
230 210
 
231 211
 
212
+	@TestResource
232 213
 	def test_simplecall(self):
233
-		resource = jsonrpc.server.JSON_RPC()
234
-		resource.customize(SimpleEventHandler)
235
-
236
-		request = DummyRequest([''])
237
-		request.getCookie = mock.Mock()
238 214
 		request.content = StringIO.StringIO('{"jsonrpc": "2.0", "params": %s, "method": "echo", "id": "%s"}' % (jsonrpc.jsonutil.encode([self.param]), self.id_))
239 215
 
240
-		d = _render(resource, request)
241
-
242
-		@d.addCallback
243
-		def rendered(ignored):
244
-			self.assertEqual(len(request.written), 1)
245
-			data = jsonrpc.jsonutil.decode(request.written[0])
246
-
247
-			self.assertEqual(data['id'], self.id_)
248
-			self.assertEqual(data['result'], self.param)
249
-		return d
216
+	@test_simplecall
217
+	def rendered(ignored):
218
+		self.assertEqual(len(request.written), 1)
219
+		data = jsonrpc.jsonutil.decode(request.written[0])
250 220
 
251
-	def test_notify(self):
252
-		resource = jsonrpc.server.JSON_RPC()
253
-		resource.customize(SimpleEventHandler)
221
+		self.assertEqual(data['id'], self.id_)
222
+		self.assertEqual(data['result'], self.param)
254 223
 
255
-		request = DummyRequest([''])
256
-		request.getCookie = mock.Mock()
224
+	@TestResource
225
+	def test_notify(self, request, resource):
257 226
 		request.content = StringIO.StringIO('{"jsonrpc": "2.0", "params": {"v": %s}, "method": "echo"}' % (jsonrpc.jsonutil.encode(self.param)))
258 227
 
259
-		d = _render(resource, request)
228
+	@test_notify
229
+	def test_notify(ignored, self, request, resource):
230
+		self.assertEqual(len(request.written), 0)
260 231
 
261
-		@d.addCallback
262
-		def rendered(ignored):
263
-			self.assertEqual(len(request.written), 0)
264 232
 
265
-		return d
266
-
267
-
268
-	def test_kwcall(self):
269
-		resource = jsonrpc.server.JSON_RPC()
270
-		resource.customize(SimpleEventHandler)
271
-
272
-		request = DummyRequest([''])
273
-		request.getCookie = mock.Mock()
233
+	@TestResource
234
+	def _test_kwcall(self, request, resource):
274 235
 		request.content = StringIO.StringIO('{"jsonrpc": "2.0", "params": {"v": %s}, "method": "echo", "id": "%s"}' % (jsonrpc.jsonutil.encode(self.param), self.id_))
275 236
 
276
-		d = _render(resource, request)
277
-
278
-		@d.addCallback
279
-		def rendered(ignored):
280
-			self.assertEqual(len(request.written), 1)
281
-			data = jsonrpc.jsonutil.decode(request.written[0])
237
+	@_test_kwcall
238
+	def test_kwcall_id(ignored, self, request, resource):
239
+		self.assertEqual(len(request.written), 1)
240
+		data = jsonrpc.jsonutil.decode(request.written[0])
282 241
 
283
-			self.assertEqual(data['id'], self.id_)
284
-			self.assertEqual(data['result'], self.param)
242
+		self.assertEqual(data['id'], self.id_)
285 243
 
286
-		return d
244
+	@_test_kwcall
245
+	def test_kwcall_result(ignored, self, request, resource):
246
+		data = jsonrpc.jsonutil.decode(request.written[0])
287 247
 
248
+		self.assertEqual(data['result'], self.param)
288 249
 
289
-	def test_err(self):
290
-		resource = jsonrpc.server.JSON_RPC()
291
-		resource.customize(SimpleEventHandler)
292
-
293
-		request = DummyRequest([''])
294
-		request.getCookie = mock.Mock()
250
+	@TestResource
251
+	def test_err(self, request, resource):
295 252
 		request.content = StringIO.StringIO('{"jsonrpc": "2.0", "params": [1, "sss"], "method": "add", "id": "%s"}' % self.id_)
253
+		return request, resource
296 254
 
297
-		d = _render(resource, request)
298
-
299
-		@d.addCallback
300
-		def rendered(ignored, *a):
301
-			self.assertEqual(len(request.written), 1)
302
-			data = jsonrpc.jsonutil.decode(request.written[0])
303
-
304
-			self.assertEqual(data['id'], self.id_)
305
-			self.assertTrue(data.get('error', False))
306
-		return rendered
255
+	@test_err
256
+	def test_err(ignored, self, request, resource):
257
+		self.assertEqual(len(request.written), 1)
258
+		data = jsonrpc.jsonutil.decode(request.written[0])
307 259
 
308
-	def test_batchcall(self):
309
-		resource = jsonrpc.server.JSON_RPC()
310
-		resource.customize(SimpleEventHandler)
260
+		self.assertEqual(data['id'], self.id_)
261
+		self.assertTrue(data.get('error', False))
311 262
 
312
-		request = DummyRequest([''])
263
+	@TestResource
264
+	def _test_batchcall(self, request, resource):
313 265
 		request.content = StringIO.StringIO(
314 266
 			'[{"jsonrpc": "2.0", "params": [1, 2], "method": "add", "id": "1"},'
315 267
 				'{"jsonrpc": "2.0", "params": {"a": 3, "b": 2}, "method": "add", "id": "2"}]'
316 268
 		)
317
-		request.getCookie = mock.Mock()
318
-
319
-		d = _render(resource, request)
320
-
321
-		@d.addCallback
322
-		def rendered(ignored, *a):
323
-			self.assertEqual(len(request.written), 1)
324
-			data = jsonrpc.jsonutil.decode(request.written[0])
325
-			self.assertEqual(len(data), 2)
326
-			self.assertEqual(set(x['id'] for x in data), set("12"))
327
-			self.assertEqual(set(x['result'] for x in data), set([3,5]))
328
-
329
-			self.assertFalse(any(x.get('error', False) for x in data))
330
-		return rendered
331
-
332
-	def test_batchcall_1err(self):
333
-		resource = jsonrpc.server.JSON_RPC()
334
-		resource.customize(SimpleEventHandler)
335
-
336
-		request = DummyRequest([''])
269
+		return request, resource
270
+
271
+	@_test_batchcall
272
+	def test_batchcall1(ignored, self, request, resource):
273
+		self.assertEqual(len(request.written), 1)
274
+
275
+	@_test_batchcall
276
+	def test_batchcall2(ignored, self, request, resource):
277
+		data = jsonrpc.jsonutil.decode(request.written[0])
278
+		self.assertEqual(len(data), 2)
279
+
280
+	@_test_batchcall
281
+	def test_batchcall3(ignored, self, request, resource):
282
+		data = jsonrpc.jsonutil.decode(request.written[0])
283
+		self.assertEqual(set(x['result'] for x in data), set([3,5]))
284
+
285
+	@_test_batchcall
286
+	def test_batchcall4(ignored, self, request, resource):
287
+		data = jsonrpc.jsonutil.decode(request.written[0])
288
+		self.assertEqual(set(x['id'] for x in data), set("12"))
289
+
290
+	@_test_batchcall
291
+	def test_batchcall5(ignored, self, request, resource):
292
+		data = jsonrpc.jsonutil.decode(request.written[0])
293
+		self.assertFalse(any(x.get('error', False) for x in data))
294
+
295
+	@TestResource
296
+	def _test_batchcall_1err(self, request, resource):
337 297
 		request.content = StringIO.StringIO(
338 298
 			'[{"jsonrpc": "2.0", "params": [1, 2], "method": "add", "id": "1"},'
339 299
 				'{"jsonrpc": "2.0", "params": {"a": "3", "b": 2}, "method": "add", "id": "2"}]'
340 300
 		)
341
-		request.getCookie = mock.Mock()
301
+		return request, resource
342 302
 
343
-		d = _render(resource, request)
303
+	@_test_batchcall_1err
304
+	def test_batchcall_1err_1(ignored, self, request, resource):
305
+		self.assertEqual(len(request.written), 1)
344 306
 
345
-		@d.addCallback
346
-		def rendered(ignored, *a):
347
-			self.assertEqual(len(request.written), 1)
348
-			data = jsonrpc.jsonutil.decode(request.written[0])
349
-			self.assertEqual(len(data), 2)
350
-			self.assertEqual(set(x['id'] for x in data), set("12"))
351
-			self.assertEqual(set(x.get('result', False) for x in data), set([3,False]))
307
+	@_test_batchcall_1err
308
+	def test_batchcall_1err_2(ignored, self, request, resource):
309
+		data = jsonrpc.jsonutil.decode(request.written[0])
310
+		self.assertEqual(len(data), 2)
352 311
 
353
-			self.assertEqual(len(filter(None, [x.get('error') for x in data])), 1)
354
-		return rendered
312
+	@_test_batchcall_1err
313
+	def test_batchcall_1err_3(ignored, self, request, resource):
314
+		data = jsonrpc.jsonutil.decode(request.written[0])
315
+		self.assertEqual(set(x['id'] for x in data), set("12"))
355 316
 
317
+	@_test_batchcall_1err
318
+	def test_batchcall_1err_4(ignored, self, request, resource):
319
+		data = jsonrpc.jsonutil.decode(request.written[0])
320
+		self.assertEqual(set(x.get('result', False) for x in data), set([3,False]))
356 321
 
357
-	def test_batchcall_emptylist(self):
358
-		resource = jsonrpc.server.JSON_RPC()
359
-		resource.customize(SimpleEventHandler)
322
+	@_test_batchcall_1err
323
+	def test_batchcall_1err_5(ignored, self, request, resource):
324
+		data = jsonrpc.jsonutil.decode(request.written[0])
325
+		self.assertEqual(len(filter(None, [x.get('error') for x in data])), 1)
360 326
 
361
-		request = DummyRequest([''])
362 327
 
328
+	@TestResource
329
+	def _test_batchcall_emptylist(self, request, resource):
363 330
 		request.content = StringIO.StringIO('[]')
364
-		request.getCookie = mock.Mock()
365
-
366
-		d = _render(resource, request)
367 331
 
368
-		@d.addCallback
369
-		def rendered(ignored, *a):
370
-			data = jsonrpc.jsonutil.decode(request.written[0])
371
-			self.assertEqual(data, {"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request."}, "id": None})
372
-		return rendered
332
+	@_test_batchcall_emptylist
333
+	def test_batchcall_emptylist(ignored, self, request, resource):
334
+		data = jsonrpc.jsonutil.decode(request.written[0])
335
+		self.assertEqual(data, {"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request."}, "id": None})
373 336
 
374 337