jimson-temp 0.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.rdoc +86 -0
- data/LICENSE.txt +17 -0
- data/README.md +29 -0
- data/Rakefile +31 -0
- data/VERSION +1 -0
- data/lib/jimson-temp.rb +8 -0
- data/lib/jimson/client.rb +180 -0
- data/lib/jimson/client/error.rb +23 -0
- data/lib/jimson/handler.rb +25 -0
- data/lib/jimson/request.rb +25 -0
- data/lib/jimson/response.rb +30 -0
- data/lib/jimson/router.rb +24 -0
- data/lib/jimson/router/map.rb +75 -0
- data/lib/jimson/server.rb +225 -0
- data/lib/jimson/server/error.rb +66 -0
- data/spec/client_spec.rb +191 -0
- data/spec/handler_spec.rb +62 -0
- data/spec/router_spec.rb +75 -0
- data/spec/server_spec.rb +466 -0
- data/spec/spec_helper.rb +7 -0
- metadata +134 -0
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Jimson
|
4
|
+
describe Handler do
|
5
|
+
|
6
|
+
class FooHandler
|
7
|
+
extend Jimson::Handler
|
8
|
+
|
9
|
+
jimson_expose :to_s, :bye
|
10
|
+
|
11
|
+
jimson_exclude :hi, :bye
|
12
|
+
|
13
|
+
def hi
|
14
|
+
'hi'
|
15
|
+
end
|
16
|
+
|
17
|
+
def bye
|
18
|
+
'bye'
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_s
|
22
|
+
'foo'
|
23
|
+
end
|
24
|
+
|
25
|
+
def so_exposed
|
26
|
+
"I'm so exposed!"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
let(:foo) { FooHandler.new }
|
31
|
+
|
32
|
+
describe "#jimson_expose" do
|
33
|
+
it "exposes a method even if it was defined on Object" do
|
34
|
+
foo.class.jimson_exposed_methods.should include('to_s')
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "#jimson_exclude" do
|
39
|
+
context "when a method was not explicitly exposed" do
|
40
|
+
it "excludes the method" do
|
41
|
+
foo.class.jimson_exposed_methods.should_not include('hi')
|
42
|
+
end
|
43
|
+
end
|
44
|
+
context "when a method was explicitly exposed" do
|
45
|
+
it "does not exclude the method" do
|
46
|
+
foo.class.jimson_exposed_methods.should include('bye')
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "#jimson_exposed_methods" do
|
52
|
+
it "doesn't include methods defined on Object" do
|
53
|
+
foo.class.jimson_exposed_methods.should_not include('object_id')
|
54
|
+
end
|
55
|
+
it "includes methods defined on the extending class but not on Object" do
|
56
|
+
foo.class.jimson_exposed_methods.should include('so_exposed')
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
data/spec/router_spec.rb
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Jimson
|
4
|
+
describe Router do
|
5
|
+
|
6
|
+
let(:router) { Router.new }
|
7
|
+
|
8
|
+
class RouterFooHandler
|
9
|
+
extend Jimson::Handler
|
10
|
+
|
11
|
+
def hi
|
12
|
+
'hi'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class RouterBarHandler
|
17
|
+
extend Jimson::Handler
|
18
|
+
|
19
|
+
def bye
|
20
|
+
'bye'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class RouterBazHandler
|
25
|
+
extend Jimson::Handler
|
26
|
+
|
27
|
+
def meh
|
28
|
+
'mehkayla'
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
describe '#draw' do
|
34
|
+
context 'when given non-nested namespaces' do
|
35
|
+
it 'takes a block with a DSL to set the root and namespaces' do
|
36
|
+
router.draw do
|
37
|
+
root RouterFooHandler
|
38
|
+
namespace 'ns', RouterBarHandler
|
39
|
+
end
|
40
|
+
|
41
|
+
router.handler_for_method('hi').should be_a(RouterFooHandler)
|
42
|
+
router.handler_for_method('ns.hi').should be_a(RouterBarHandler)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context 'when given nested namespaces' do
|
47
|
+
it 'takes a block with a DSL to set the root and namespaces' do
|
48
|
+
router.draw do
|
49
|
+
root RouterFooHandler
|
50
|
+
namespace 'ns1' do
|
51
|
+
root RouterBazHandler
|
52
|
+
namespace 'ns2', RouterBarHandler
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
router.handler_for_method('hi').should be_a(RouterFooHandler)
|
57
|
+
router.handler_for_method('ns1.hi').should be_a(RouterBazHandler)
|
58
|
+
router.handler_for_method('ns1.ns2.hi').should be_a(RouterBarHandler)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe '#jimson_methods' do
|
64
|
+
it 'returns an array of namespaced method names from all registered handlers' do
|
65
|
+
router.draw do
|
66
|
+
root RouterFooHandler
|
67
|
+
namespace 'foo', RouterBarHandler
|
68
|
+
end
|
69
|
+
|
70
|
+
router.jimson_methods.sort.should == ['hi', 'foo.bye'].sort
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
end
|
data/spec/server_spec.rb
ADDED
@@ -0,0 +1,466 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'rack/test'
|
3
|
+
|
4
|
+
module Jimson
|
5
|
+
describe Server do
|
6
|
+
include Rack::Test::Methods
|
7
|
+
|
8
|
+
class TestHandler
|
9
|
+
extend Jimson::Handler
|
10
|
+
|
11
|
+
def subtract(a, b = nil)
|
12
|
+
if a.is_a?(Hash)
|
13
|
+
return a['minuend'] - a['subtrahend']
|
14
|
+
else
|
15
|
+
return a - b
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def sum(a,b,c)
|
20
|
+
a + b + c
|
21
|
+
end
|
22
|
+
|
23
|
+
def car(array)
|
24
|
+
array.first
|
25
|
+
end
|
26
|
+
|
27
|
+
def notify_hello(*args)
|
28
|
+
# notification, doesn't do anything
|
29
|
+
end
|
30
|
+
|
31
|
+
def update(*args)
|
32
|
+
# notification, doesn't do anything
|
33
|
+
end
|
34
|
+
|
35
|
+
def get_data
|
36
|
+
['hello', 5]
|
37
|
+
end
|
38
|
+
|
39
|
+
def ugly_method
|
40
|
+
raise RuntimeError
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
class OtherHandler
|
45
|
+
extend Jimson::Handler
|
46
|
+
|
47
|
+
def multiply(a,b)
|
48
|
+
a * b
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
INVALID_RESPONSE_EXPECTATION = {
|
53
|
+
'jsonrpc' => '2.0',
|
54
|
+
'error' => {
|
55
|
+
'code' => -32600,
|
56
|
+
'message' => 'The JSON sent is not a valid Request object.'
|
57
|
+
},
|
58
|
+
'id' => nil
|
59
|
+
}
|
60
|
+
let(:router) do
|
61
|
+
router = Router.new.draw do
|
62
|
+
root TestHandler.new
|
63
|
+
namespace 'other', OtherHandler.new
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
let(:app) do
|
68
|
+
Server.new(router, :environment => "production")
|
69
|
+
end
|
70
|
+
|
71
|
+
def post_json(hash)
|
72
|
+
post '/', MultiJson.encode(hash), {'Content-Type' => 'application/json'}
|
73
|
+
end
|
74
|
+
|
75
|
+
before(:each) do
|
76
|
+
@url = SPEC_URL
|
77
|
+
end
|
78
|
+
|
79
|
+
it "exposes the given options" do
|
80
|
+
app.opts.should == { :environment => "production" }
|
81
|
+
end
|
82
|
+
|
83
|
+
describe "receiving a request with positional parameters" do
|
84
|
+
context "when no errors occur" do
|
85
|
+
it "returns a response with 'result'" do
|
86
|
+
req = {
|
87
|
+
'jsonrpc' => '2.0',
|
88
|
+
'method' => 'subtract',
|
89
|
+
'params' => [24, 20],
|
90
|
+
'id' => 1
|
91
|
+
}
|
92
|
+
post_json(req)
|
93
|
+
|
94
|
+
last_response.should be_ok
|
95
|
+
resp = MultiJson.decode(last_response.body)
|
96
|
+
resp.should == {
|
97
|
+
'jsonrpc' => '2.0',
|
98
|
+
'result' => 4,
|
99
|
+
'id' => 1
|
100
|
+
}
|
101
|
+
end
|
102
|
+
|
103
|
+
it "handles an array in the parameters" do
|
104
|
+
req = {
|
105
|
+
'jsonrpc' => '2.0',
|
106
|
+
'method' => 'car',
|
107
|
+
'params' => [['a', 'b']],
|
108
|
+
'id' => 1
|
109
|
+
}
|
110
|
+
post_json(req)
|
111
|
+
|
112
|
+
last_response.should be_ok
|
113
|
+
resp = MultiJson.decode(last_response.body)
|
114
|
+
resp.should == {
|
115
|
+
'jsonrpc' => '2.0',
|
116
|
+
'result' => 'a',
|
117
|
+
'id' => 1
|
118
|
+
}
|
119
|
+
end
|
120
|
+
|
121
|
+
it "handles bignums" do
|
122
|
+
req = {
|
123
|
+
'jsonrpc' => '2.0',
|
124
|
+
'method' => 'subtract',
|
125
|
+
'params' => [24, 20],
|
126
|
+
'id' => 123456789_123456789_123456789
|
127
|
+
}
|
128
|
+
post_json(req)
|
129
|
+
|
130
|
+
last_response.should be_ok
|
131
|
+
resp = MultiJson.decode(last_response.body)
|
132
|
+
resp.should == {
|
133
|
+
'jsonrpc' => '2.0',
|
134
|
+
'result' => 4,
|
135
|
+
'id' => 123456789_123456789_123456789
|
136
|
+
}
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
describe "receiving a request with named parameters" do
|
142
|
+
context "when no errors occur" do
|
143
|
+
it "returns a response with 'result'" do
|
144
|
+
req = {
|
145
|
+
'jsonrpc' => '2.0',
|
146
|
+
'method' => 'subtract',
|
147
|
+
'params' => {'subtrahend'=> 20, 'minuend' => 24},
|
148
|
+
'id' => 1
|
149
|
+
}
|
150
|
+
post_json(req)
|
151
|
+
|
152
|
+
last_response.should be_ok
|
153
|
+
resp = MultiJson.decode(last_response.body)
|
154
|
+
resp.should == {
|
155
|
+
'jsonrpc' => '2.0',
|
156
|
+
'result' => 4,
|
157
|
+
'id' => 1
|
158
|
+
}
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
describe "receiving a notification" do
|
164
|
+
context "when no errors occur" do
|
165
|
+
it "returns no response" do
|
166
|
+
req = {
|
167
|
+
'jsonrpc' => '2.0',
|
168
|
+
'method' => 'update',
|
169
|
+
'params' => [1,2,3,4,5]
|
170
|
+
}
|
171
|
+
post_json(req)
|
172
|
+
last_response.body.should be_empty
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
describe "receiving a call for a non-existent method" do
|
178
|
+
it "returns an error response" do
|
179
|
+
req = {
|
180
|
+
'jsonrpc' => '2.0',
|
181
|
+
'method' => 'foobar',
|
182
|
+
'id' => 1
|
183
|
+
}
|
184
|
+
post_json(req)
|
185
|
+
|
186
|
+
resp = MultiJson.decode(last_response.body)
|
187
|
+
resp.should == {
|
188
|
+
'jsonrpc' => '2.0',
|
189
|
+
'error' => {
|
190
|
+
'code' => -32601,
|
191
|
+
'message' => "Method 'foobar' not found."
|
192
|
+
},
|
193
|
+
'id' => 1
|
194
|
+
}
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
describe "receiving a call for a method which exists but is not exposed" do
|
199
|
+
it "returns an error response" do
|
200
|
+
req = {
|
201
|
+
'jsonrpc' => '2.0',
|
202
|
+
'method' => 'object_id',
|
203
|
+
'id' => 1
|
204
|
+
}
|
205
|
+
post_json(req)
|
206
|
+
|
207
|
+
resp = MultiJson.decode(last_response.body)
|
208
|
+
resp.should == {
|
209
|
+
'jsonrpc' => '2.0',
|
210
|
+
'error' => {
|
211
|
+
'code' => -32601,
|
212
|
+
'message' => "Method 'object_id' not found."
|
213
|
+
},
|
214
|
+
'id' => 1
|
215
|
+
}
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
describe "receiving a call with the wrong number of params" do
|
220
|
+
it "returns an error response" do
|
221
|
+
req = {
|
222
|
+
'jsonrpc' => '2.0',
|
223
|
+
'method' => 'subtract',
|
224
|
+
'params' => [1,2,3],
|
225
|
+
'id' => 1
|
226
|
+
}
|
227
|
+
post_json(req)
|
228
|
+
|
229
|
+
resp = MultiJson.decode(last_response.body)
|
230
|
+
resp.should == {
|
231
|
+
'jsonrpc' => '2.0',
|
232
|
+
'error' => {
|
233
|
+
'code' => -32602,
|
234
|
+
'message' => 'Invalid method parameter(s).'
|
235
|
+
},
|
236
|
+
'id' => 1
|
237
|
+
}
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
describe "receiving a call for ugly method" do
|
242
|
+
context "by default" do
|
243
|
+
it "returns only global error without stack trace" do
|
244
|
+
req = {
|
245
|
+
'jsonrpc' => '2.0',
|
246
|
+
'method' => 'ugly_method',
|
247
|
+
'id' => 1
|
248
|
+
}
|
249
|
+
post_json(req)
|
250
|
+
|
251
|
+
resp = MultiJson.decode(last_response.body)
|
252
|
+
resp.should == {
|
253
|
+
'jsonrpc' => '2.0',
|
254
|
+
'error' => {
|
255
|
+
'code' => -32099,
|
256
|
+
'message' => 'Server application error'
|
257
|
+
},
|
258
|
+
'id' => 1
|
259
|
+
}
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
context "with 'show_errors' enabled" do
|
264
|
+
it "returns an error name and first line of the stack trace" do
|
265
|
+
req = {
|
266
|
+
'jsonrpc' => '2.0',
|
267
|
+
'method' => 'ugly_method',
|
268
|
+
'id' => 1
|
269
|
+
}
|
270
|
+
|
271
|
+
app = Server.new(router, :environment => "production", :show_errors => true)
|
272
|
+
|
273
|
+
# have to make a new Rack::Test browser since this server is different than the normal one
|
274
|
+
browser = Rack::Test::Session.new(Rack::MockSession.new(app))
|
275
|
+
browser.post '/', MultiJson.encode(req), {'Content-Type' => 'application/json'}
|
276
|
+
|
277
|
+
resp = MultiJson.decode(browser.last_response.body)
|
278
|
+
resp.should == {
|
279
|
+
'jsonrpc' => '2.0',
|
280
|
+
'error' => {
|
281
|
+
'code' => -32099,
|
282
|
+
'message' => "Server application error: RuntimeError at #{__FILE__}:40:in `ugly_method'"
|
283
|
+
},
|
284
|
+
'id' => 1
|
285
|
+
}
|
286
|
+
end
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
290
|
+
describe "receiving invalid JSON" do
|
291
|
+
it "returns an error response" do
|
292
|
+
req = MultiJson.encode({
|
293
|
+
'jsonrpc' => '2.0',
|
294
|
+
'method' => 'foobar',
|
295
|
+
'id' => 1
|
296
|
+
})
|
297
|
+
req += '}' # make the json invalid
|
298
|
+
post '/', req, {'Content-type' => 'application/json'}
|
299
|
+
|
300
|
+
resp = MultiJson.decode(last_response.body)
|
301
|
+
resp.should == {
|
302
|
+
'jsonrpc' => '2.0',
|
303
|
+
'error' => {
|
304
|
+
'code' => -32700,
|
305
|
+
'message' => 'Invalid JSON was received by the server. An error occurred on the server while parsing the JSON text.'
|
306
|
+
},
|
307
|
+
'id' => nil
|
308
|
+
}
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
312
|
+
describe "receiving an invalid request" do
|
313
|
+
context "when the request is not a batch" do
|
314
|
+
it "returns an error response" do
|
315
|
+
req = {
|
316
|
+
'jsonrpc' => '2.0',
|
317
|
+
'method' => 1 # method as int is invalid
|
318
|
+
}
|
319
|
+
post_json(req)
|
320
|
+
resp = MultiJson.decode(last_response.body)
|
321
|
+
resp.should == INVALID_RESPONSE_EXPECTATION
|
322
|
+
end
|
323
|
+
end
|
324
|
+
|
325
|
+
context "when the request is an empty batch" do
|
326
|
+
it "returns an error response" do
|
327
|
+
req = []
|
328
|
+
post_json(req)
|
329
|
+
resp = MultiJson.decode(last_response.body)
|
330
|
+
resp.should == INVALID_RESPONSE_EXPECTATION
|
331
|
+
end
|
332
|
+
end
|
333
|
+
|
334
|
+
context "when the request is an invalid batch" do
|
335
|
+
it "returns an error response" do
|
336
|
+
req = [1,2]
|
337
|
+
post_json(req)
|
338
|
+
resp = MultiJson.decode(last_response.body)
|
339
|
+
resp.should == [INVALID_RESPONSE_EXPECTATION, INVALID_RESPONSE_EXPECTATION]
|
340
|
+
end
|
341
|
+
end
|
342
|
+
end
|
343
|
+
|
344
|
+
describe "receiving a valid batch request" do
|
345
|
+
context "when not all requests are notifications" do
|
346
|
+
it "returns an array of responses" do
|
347
|
+
reqs = [
|
348
|
+
{'jsonrpc' => '2.0', 'method' => 'sum', 'params' => [1,2,4], 'id' => '1'},
|
349
|
+
{'jsonrpc' => '2.0', 'method' => 'notify_hello', 'params' => [7]},
|
350
|
+
{'jsonrpc' => '2.0', 'method' => 'subtract', 'params' => [42,23], 'id' => '2'},
|
351
|
+
{'foo' => 'boo'},
|
352
|
+
{'jsonrpc' => '2.0', 'method' => 'foo.get', 'params' => {'name' => 'myself'}, 'id' => '5'},
|
353
|
+
{'jsonrpc' => '2.0', 'method' => 'get_data', 'id' => '9'}
|
354
|
+
]
|
355
|
+
post_json(reqs)
|
356
|
+
resp = MultiJson.decode(last_response.body)
|
357
|
+
resp.should == [
|
358
|
+
{'jsonrpc' => '2.0', 'result' => 7, 'id' => '1'},
|
359
|
+
{'jsonrpc' => '2.0', 'result' => 19, 'id' => '2'},
|
360
|
+
{'jsonrpc' => '2.0', 'error' => {'code' => -32600, 'message' => 'The JSON sent is not a valid Request object.'}, 'id' => nil},
|
361
|
+
{'jsonrpc' => '2.0', 'error' => {'code' => -32601, 'message' => "Method 'foo.get' not found."}, 'id' => '5'},
|
362
|
+
{'jsonrpc' => '2.0', 'result' => ['hello', 5], 'id' => '9'}
|
363
|
+
]
|
364
|
+
end
|
365
|
+
end
|
366
|
+
|
367
|
+
context "when all the requests are notifications" do
|
368
|
+
it "returns no response" do
|
369
|
+
req = [
|
370
|
+
{
|
371
|
+
'jsonrpc' => '2.0',
|
372
|
+
'method' => 'update',
|
373
|
+
'params' => [1,2,3,4,5]
|
374
|
+
},
|
375
|
+
{
|
376
|
+
'jsonrpc' => '2.0',
|
377
|
+
'method' => 'update',
|
378
|
+
'params' => [1,2,3,4,5]
|
379
|
+
}
|
380
|
+
]
|
381
|
+
post_json(req)
|
382
|
+
last_response.body.should be_empty
|
383
|
+
end
|
384
|
+
end
|
385
|
+
end
|
386
|
+
|
387
|
+
describe "receiving a 'system.' request" do
|
388
|
+
context "when the request is 'isAlive'" do
|
389
|
+
it "returns response 'true'" do
|
390
|
+
req = {
|
391
|
+
'jsonrpc' => '2.0',
|
392
|
+
'method' => 'system.isAlive',
|
393
|
+
'params' => [],
|
394
|
+
'id' => 1
|
395
|
+
}
|
396
|
+
post_json(req)
|
397
|
+
|
398
|
+
last_response.should be_ok
|
399
|
+
resp = MultiJson.decode(last_response.body)
|
400
|
+
resp.should == {
|
401
|
+
'jsonrpc' => '2.0',
|
402
|
+
'result' => true,
|
403
|
+
'id' => 1
|
404
|
+
}
|
405
|
+
end
|
406
|
+
end
|
407
|
+
context "when the request is 'system.listMethods'" do
|
408
|
+
it "returns response with all jimson_exposed_methods on the handler(s) as strings" do
|
409
|
+
req = {
|
410
|
+
'jsonrpc' => '2.0',
|
411
|
+
'method' => 'system.listMethods',
|
412
|
+
'params' => [],
|
413
|
+
'id' => 1
|
414
|
+
}
|
415
|
+
post_json(req)
|
416
|
+
|
417
|
+
last_response.should be_ok
|
418
|
+
resp = MultiJson.decode(last_response.body)
|
419
|
+
resp['jsonrpc'].should == '2.0'
|
420
|
+
resp['id'].should == 1
|
421
|
+
expected = ['get_data', 'notify_hello', 'subtract', 'sum', 'car', 'ugly_method', 'update', 'system.isAlive', 'system.listMethods', 'other.multiply']
|
422
|
+
(resp['result'] - expected).should == []
|
423
|
+
end
|
424
|
+
end
|
425
|
+
end
|
426
|
+
|
427
|
+
describe ".with_routes" do
|
428
|
+
it "creates a server with a router by passing the block to Router#draw" do
|
429
|
+
app = Server.with_routes do
|
430
|
+
root TestHandler.new
|
431
|
+
namespace 'foo', OtherHandler.new
|
432
|
+
end
|
433
|
+
|
434
|
+
# have to make a new Rack::Test browser since this server is different than the normal one
|
435
|
+
browser = Rack::Test::Session.new(Rack::MockSession.new(app))
|
436
|
+
|
437
|
+
req = {
|
438
|
+
'jsonrpc' => '2.0',
|
439
|
+
'method' => 'foo.multiply',
|
440
|
+
'params' => [2, 3],
|
441
|
+
'id' => 1
|
442
|
+
}
|
443
|
+
browser.post '/', MultiJson.encode(req), {'Content-Type' => 'application/json'}
|
444
|
+
|
445
|
+
browser.last_response.should be_ok
|
446
|
+
resp = MultiJson.decode(browser.last_response.body)
|
447
|
+
resp.should == {
|
448
|
+
'jsonrpc' => '2.0',
|
449
|
+
'result' => 6,
|
450
|
+
'id' => 1
|
451
|
+
}
|
452
|
+
end
|
453
|
+
|
454
|
+
context "when opts are given" do
|
455
|
+
it "passes the opts to the new server" do
|
456
|
+
app = Server.with_routes(:show_errors => true) do
|
457
|
+
root TestHandler.new
|
458
|
+
namespace 'foo', OtherHandler.new
|
459
|
+
end
|
460
|
+
|
461
|
+
app.show_errors.should be_true
|
462
|
+
end
|
463
|
+
end
|
464
|
+
end
|
465
|
+
end
|
466
|
+
end
|