jimson 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.rdoc +10 -0
- data/README.md +8 -0
- data/VERSION +1 -1
- data/lib/jimson/client.rb +12 -15
- data/lib/jimson/handler.rb +1 -1
- data/lib/jimson/request.rb +1 -1
- data/lib/jimson/server.rb +5 -5
- data/spec/client_spec.rb +23 -23
- data/spec/handler_spec.rb +5 -5
- data/spec/server_spec.rb +36 -18
- data/spec/spec_helper.rb +2 -1
- metadata +23 -23
data/CHANGELOG.rdoc
CHANGED
data/README.md
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# Jimson
|
2
2
|
### JSON-RPC 2.0 Client and Server for Ruby
|
3
|
+
![next build status](https://secure.travis-ci.org/chriskite/jimson.png?branch=next)
|
3
4
|
|
4
5
|
## Client: Quick Start
|
5
6
|
require 'jimson'
|
@@ -19,3 +20,10 @@
|
|
19
20
|
|
20
21
|
server = Jimson::Server.new(MyHandler.new)
|
21
22
|
server.start # serve with webrick on http://0.0.0.0:8999/
|
23
|
+
|
24
|
+
## JSON Engine
|
25
|
+
Jimson uses multi\_json, so you can load the JSON library of your choice in your application and Jimson will use it automatically.
|
26
|
+
|
27
|
+
For example, require the 'json' gem in your application:
|
28
|
+
require 'json'
|
29
|
+
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.5.0
|
data/lib/jimson/client.rb
CHANGED
@@ -1,11 +1,6 @@
|
|
1
1
|
require 'blankslate'
|
2
|
-
|
3
|
-
class Client < BlankSlate
|
4
|
-
end
|
5
|
-
end
|
6
|
-
|
2
|
+
require 'multi_json'
|
7
3
|
require 'rest-client'
|
8
|
-
require 'jimson/client/error'
|
9
4
|
require 'jimson/request'
|
10
5
|
require 'jimson/response'
|
11
6
|
|
@@ -27,7 +22,7 @@ module Jimson
|
|
27
22
|
resp = send_single_request(sym.to_s, args)
|
28
23
|
|
29
24
|
begin
|
30
|
-
data =
|
25
|
+
data = MultiJson.decode(resp)
|
31
26
|
rescue
|
32
27
|
raise Client::Error::InvalidJSON.new(resp)
|
33
28
|
end
|
@@ -40,12 +35,12 @@ module Jimson
|
|
40
35
|
end
|
41
36
|
|
42
37
|
def send_single_request(method, args)
|
43
|
-
post_data = {
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
38
|
+
post_data = MultiJson.encode({
|
39
|
+
'jsonrpc' => JSON_RPC_VERSION,
|
40
|
+
'method' => method,
|
41
|
+
'params' => args,
|
42
|
+
'id' => self.class.make_id
|
43
|
+
})
|
49
44
|
resp = RestClient.post(@url, post_data, :content_type => 'application/json')
|
50
45
|
if resp.nil? || resp.body.nil? || resp.body.empty?
|
51
46
|
raise Client::Error::InvalidResponse.new
|
@@ -55,7 +50,7 @@ module Jimson
|
|
55
50
|
end
|
56
51
|
|
57
52
|
def send_batch_request(batch)
|
58
|
-
post_data = batch
|
53
|
+
post_data = MultiJson.encode(batch)
|
59
54
|
resp = RestClient.post(@url, post_data, :content_type => 'application/json')
|
60
55
|
if resp.nil? || resp.body.nil? || resp.body.empty?
|
61
56
|
raise Client::Error::InvalidResponse.new
|
@@ -121,7 +116,7 @@ module Jimson
|
|
121
116
|
response = send_batch_request(batch)
|
122
117
|
|
123
118
|
begin
|
124
|
-
responses =
|
119
|
+
responses = MultiJson.decode(response)
|
125
120
|
rescue
|
126
121
|
raise Client::Error::InvalidJSON.new(json)
|
127
122
|
end
|
@@ -171,3 +166,5 @@ module Jimson
|
|
171
166
|
|
172
167
|
end
|
173
168
|
end
|
169
|
+
|
170
|
+
require 'jimson/client/error'
|
data/lib/jimson/handler.rb
CHANGED
@@ -18,7 +18,7 @@ module Jimson
|
|
18
18
|
def jimson_exposed_methods
|
19
19
|
@jimson_exposed_methods ||= []
|
20
20
|
@jimson_excluded_methods ||= []
|
21
|
-
(jimson_default_methods - @jimson_excluded_methods + @jimson_exposed_methods).sort
|
21
|
+
(jimson_default_methods - @jimson_excluded_methods + @jimson_exposed_methods).sort
|
22
22
|
end
|
23
23
|
|
24
24
|
end
|
data/lib/jimson/request.rb
CHANGED
data/lib/jimson/server.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'rack'
|
2
2
|
require 'rack/request'
|
3
3
|
require 'rack/response'
|
4
|
-
require '
|
4
|
+
require 'multi_json'
|
5
5
|
require 'jimson/handler'
|
6
6
|
require 'jimson/server/error'
|
7
7
|
|
@@ -87,7 +87,7 @@ module Jimson
|
|
87
87
|
|
88
88
|
return nil if response.nil? || (response.respond_to?(:empty?) && response.empty?)
|
89
89
|
|
90
|
-
response
|
90
|
+
MultiJson.encode(response)
|
91
91
|
end
|
92
92
|
|
93
93
|
def handle_request(request)
|
@@ -111,7 +111,7 @@ module Jimson
|
|
111
111
|
'jsonrpc' => [String],
|
112
112
|
'method' => [String],
|
113
113
|
'params' => [Hash, Array],
|
114
|
-
'id' => [String, Fixnum, NilClass]
|
114
|
+
'id' => [String, Fixnum, Bignum, NilClass]
|
115
115
|
}
|
116
116
|
|
117
117
|
return false if !request.is_a?(Hash)
|
@@ -163,7 +163,7 @@ module Jimson
|
|
163
163
|
method.gsub!(sys_regex, '')
|
164
164
|
end
|
165
165
|
|
166
|
-
method = method.
|
166
|
+
method = method.to_s
|
167
167
|
|
168
168
|
if !handler.class.jimson_exposed_methods.include?(method) \
|
169
169
|
|| !handler.respond_to?(method)
|
@@ -202,7 +202,7 @@ module Jimson
|
|
202
202
|
end
|
203
203
|
|
204
204
|
def parse_request(post)
|
205
|
-
data =
|
205
|
+
data = MultiJson.decode(post)
|
206
206
|
rescue
|
207
207
|
raise Server::Error::ParseError.new
|
208
208
|
end
|
data/spec/client_spec.rb
CHANGED
@@ -24,13 +24,13 @@ module Jimson
|
|
24
24
|
|
25
25
|
describe "#[]" do
|
26
26
|
before(:each) do
|
27
|
-
expected = {
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
response = BOILERPLATE.merge({'result' => 42})
|
27
|
+
expected = MultiJson.encode({
|
28
|
+
'jsonrpc' => '2.0',
|
29
|
+
'method' => 'foo',
|
30
|
+
'params' => [1,2,3],
|
31
|
+
'id' => 1
|
32
|
+
})
|
33
|
+
response = MultiJson.encode(BOILERPLATE.merge({'result' => 42}))
|
34
34
|
RestClient.should_receive(:post).with(SPEC_URL, expected, {:content_type => 'application/json'}).and_return(@resp_mock)
|
35
35
|
@resp_mock.should_receive(:body).at_least(:once).and_return(response)
|
36
36
|
@client = Client.new(SPEC_URL)
|
@@ -51,15 +51,15 @@ module Jimson
|
|
51
51
|
describe "sending a single request" do
|
52
52
|
context "when using positional parameters" do
|
53
53
|
before(:each) do
|
54
|
-
@expected = {
|
54
|
+
@expected = MultiJson.encode({
|
55
55
|
'jsonrpc' => '2.0',
|
56
56
|
'method' => 'foo',
|
57
57
|
'params' => [1,2,3],
|
58
58
|
'id' => 1
|
59
|
-
|
59
|
+
})
|
60
60
|
end
|
61
61
|
it "sends a valid JSON-RPC request and returns the result" do
|
62
|
-
response = BOILERPLATE.merge({'result' => 42})
|
62
|
+
response = MultiJson.encode(BOILERPLATE.merge({'result' => 42}))
|
63
63
|
RestClient.should_receive(:post).with(SPEC_URL, @expected, {:content_type => 'application/json'}).and_return(@resp_mock)
|
64
64
|
@resp_mock.should_receive(:body).at_least(:once).and_return(response)
|
65
65
|
client = Client.new(SPEC_URL)
|
@@ -70,19 +70,19 @@ module Jimson
|
|
70
70
|
|
71
71
|
describe "sending a batch request" do
|
72
72
|
it "sends a valid JSON-RPC batch request and puts the results in the response objects" do
|
73
|
-
batch = [
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
]
|
79
|
-
|
80
|
-
response = [
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
]
|
73
|
+
batch = MultiJson.encode([
|
74
|
+
{"jsonrpc" => "2.0", "method" => "sum", "params" => [1,2,4], "id" => "1"},
|
75
|
+
{"jsonrpc" => "2.0", "method" => "subtract", "params" => [42,23], "id" => "2"},
|
76
|
+
{"jsonrpc" => "2.0", "method" => "foo_get", "params" => [{"name" => "myself"}], "id" => "5"},
|
77
|
+
{"jsonrpc" => "2.0", "method" => "get_data", "id" => "9"}
|
78
|
+
])
|
79
|
+
|
80
|
+
response = MultiJson.encode([
|
81
|
+
{"jsonrpc" => "2.0", "result" => 7, "id" => "1"},
|
82
|
+
{"jsonrpc" => "2.0", "result" => 19, "id" => "2"},
|
83
|
+
{"jsonrpc" => "2.0", "error" => {"code" => -32601, "message" => "Method not found."}, "id" => "5"},
|
84
|
+
{"jsonrpc" => "2.0", "result" => ["hello", 5], "id" => "9"}
|
85
|
+
])
|
86
86
|
|
87
87
|
ClientHelper.stub!(:make_id).and_return('1', '2', '5', '9')
|
88
88
|
RestClient.should_receive(:post).with(SPEC_URL, batch, {:content_type => 'application/json'}).and_return(@resp_mock)
|
data/spec/handler_spec.rb
CHANGED
@@ -31,29 +31,29 @@ module Jimson
|
|
31
31
|
|
32
32
|
describe "#jimson_expose" do
|
33
33
|
it "exposes a method even if it was defined on Object" do
|
34
|
-
foo.class.jimson_exposed_methods.should include(
|
34
|
+
foo.class.jimson_exposed_methods.should include('to_s')
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
38
|
describe "#jimson_exclude" do
|
39
39
|
context "when a method was not explicitly exposed" do
|
40
40
|
it "excludes the method" do
|
41
|
-
foo.class.jimson_exposed_methods.should_not include(
|
41
|
+
foo.class.jimson_exposed_methods.should_not include('hi')
|
42
42
|
end
|
43
43
|
end
|
44
44
|
context "when a method was explicitly exposed" do
|
45
45
|
it "does not exclude the method" do
|
46
|
-
foo.class.jimson_exposed_methods.should include(
|
46
|
+
foo.class.jimson_exposed_methods.should include('bye')
|
47
47
|
end
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
51
51
|
describe "#jimson_exposed_methods" do
|
52
52
|
it "doesn't include methods defined on Object" do
|
53
|
-
foo.class.jimson_exposed_methods.should_not include(
|
53
|
+
foo.class.jimson_exposed_methods.should_not include('object_id')
|
54
54
|
end
|
55
55
|
it "includes methods defined on the extending class but not on Object" do
|
56
|
-
foo.class.jimson_exposed_methods.should include(
|
56
|
+
foo.class.jimson_exposed_methods.should include('so_exposed')
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
data/spec/server_spec.rb
CHANGED
@@ -46,7 +46,7 @@ module Jimson
|
|
46
46
|
end
|
47
47
|
|
48
48
|
def post_json(hash)
|
49
|
-
post '/', hash
|
49
|
+
post '/', MultiJson.encode(hash), {'Content-Type' => 'application/json'}
|
50
50
|
end
|
51
51
|
|
52
52
|
before(:each) do
|
@@ -65,13 +65,31 @@ module Jimson
|
|
65
65
|
post_json(req)
|
66
66
|
|
67
67
|
last_response.should be_ok
|
68
|
-
resp =
|
68
|
+
resp = MultiJson.decode(last_response.body)
|
69
69
|
resp.should == {
|
70
70
|
'jsonrpc' => '2.0',
|
71
71
|
'result' => 4,
|
72
72
|
'id' => 1
|
73
73
|
}
|
74
74
|
end
|
75
|
+
|
76
|
+
it "handles bignums" do
|
77
|
+
req = {
|
78
|
+
'jsonrpc' => '2.0',
|
79
|
+
'method' => 'subtract',
|
80
|
+
'params' => [24, 20],
|
81
|
+
'id' => 123456789_123456789_123456789
|
82
|
+
}
|
83
|
+
post_json(req)
|
84
|
+
|
85
|
+
last_response.should be_ok
|
86
|
+
resp = MultiJson.decode(last_response.body)
|
87
|
+
resp.should == {
|
88
|
+
'jsonrpc' => '2.0',
|
89
|
+
'result' => 4,
|
90
|
+
'id' => 123456789_123456789_123456789
|
91
|
+
}
|
92
|
+
end
|
75
93
|
end
|
76
94
|
end
|
77
95
|
|
@@ -87,7 +105,7 @@ module Jimson
|
|
87
105
|
post_json(req)
|
88
106
|
|
89
107
|
last_response.should be_ok
|
90
|
-
resp =
|
108
|
+
resp = MultiJson.decode(last_response.body)
|
91
109
|
resp.should == {
|
92
110
|
'jsonrpc' => '2.0',
|
93
111
|
'result' => 4,
|
@@ -120,7 +138,7 @@ module Jimson
|
|
120
138
|
}
|
121
139
|
post_json(req)
|
122
140
|
|
123
|
-
resp =
|
141
|
+
resp = MultiJson.decode(last_response.body)
|
124
142
|
resp.should == {
|
125
143
|
'jsonrpc' => '2.0',
|
126
144
|
'error' => {
|
@@ -141,7 +159,7 @@ module Jimson
|
|
141
159
|
}
|
142
160
|
post_json(req)
|
143
161
|
|
144
|
-
resp =
|
162
|
+
resp = MultiJson.decode(last_response.body)
|
145
163
|
resp.should == {
|
146
164
|
'jsonrpc' => '2.0',
|
147
165
|
'error' => {
|
@@ -163,7 +181,7 @@ module Jimson
|
|
163
181
|
}
|
164
182
|
post_json(req)
|
165
183
|
|
166
|
-
resp =
|
184
|
+
resp = MultiJson.decode(last_response.body)
|
167
185
|
resp.should == {
|
168
186
|
'jsonrpc' => '2.0',
|
169
187
|
'error' => {
|
@@ -177,15 +195,15 @@ module Jimson
|
|
177
195
|
|
178
196
|
describe "receiving invalid JSON" do
|
179
197
|
it "returns an error response" do
|
180
|
-
req = {
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
198
|
+
req = MultiJson.encode({
|
199
|
+
'jsonrpc' => '2.0',
|
200
|
+
'method' => 'foobar',
|
201
|
+
'id' => 1
|
202
|
+
})
|
185
203
|
req += '}' # make the json invalid
|
186
204
|
post '/', req, {'Content-type' => 'application/json'}
|
187
205
|
|
188
|
-
resp =
|
206
|
+
resp = MultiJson.decode(last_response.body)
|
189
207
|
resp.should == {
|
190
208
|
'jsonrpc' => '2.0',
|
191
209
|
'error' => {
|
@@ -205,7 +223,7 @@ module Jimson
|
|
205
223
|
'method' => 1 # method as int is invalid
|
206
224
|
}
|
207
225
|
post_json(req)
|
208
|
-
resp =
|
226
|
+
resp = MultiJson.decode(last_response.body)
|
209
227
|
resp.should == INVALID_RESPONSE_EXPECTATION
|
210
228
|
end
|
211
229
|
end
|
@@ -214,7 +232,7 @@ module Jimson
|
|
214
232
|
it "returns an error response" do
|
215
233
|
req = []
|
216
234
|
post_json(req)
|
217
|
-
resp =
|
235
|
+
resp = MultiJson.decode(last_response.body)
|
218
236
|
resp.should == INVALID_RESPONSE_EXPECTATION
|
219
237
|
end
|
220
238
|
end
|
@@ -223,7 +241,7 @@ module Jimson
|
|
223
241
|
it "returns an error response" do
|
224
242
|
req = [1,2]
|
225
243
|
post_json(req)
|
226
|
-
resp =
|
244
|
+
resp = MultiJson.decode(last_response.body)
|
227
245
|
resp.should == [INVALID_RESPONSE_EXPECTATION, INVALID_RESPONSE_EXPECTATION]
|
228
246
|
end
|
229
247
|
end
|
@@ -241,7 +259,7 @@ module Jimson
|
|
241
259
|
{'jsonrpc' => '2.0', 'method' => 'get_data', 'id' => '9'}
|
242
260
|
]
|
243
261
|
post_json(reqs)
|
244
|
-
resp =
|
262
|
+
resp = MultiJson.decode(last_response.body)
|
245
263
|
resp.should == [
|
246
264
|
{'jsonrpc' => '2.0', 'result' => 7, 'id' => '1'},
|
247
265
|
{'jsonrpc' => '2.0', 'result' => 19, 'id' => '2'},
|
@@ -284,7 +302,7 @@ module Jimson
|
|
284
302
|
post_json(req)
|
285
303
|
|
286
304
|
last_response.should be_ok
|
287
|
-
resp =
|
305
|
+
resp = MultiJson.decode(last_response.body)
|
288
306
|
resp.should == {
|
289
307
|
'jsonrpc' => '2.0',
|
290
308
|
'result' => true,
|
@@ -303,7 +321,7 @@ module Jimson
|
|
303
321
|
post_json(req)
|
304
322
|
|
305
323
|
last_response.should be_ok
|
306
|
-
resp =
|
324
|
+
resp = MultiJson.decode(last_response.body)
|
307
325
|
resp.should == {
|
308
326
|
'jsonrpc' => '2.0',
|
309
327
|
'result' => ['subtract', 'sum', 'notify_hello', 'update', 'get_data'].sort,
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jimson
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2012-03-06 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: blankslate
|
16
|
-
requirement: &
|
16
|
+
requirement: &12957520 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 2.1.2.3
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *12957520
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rest-client
|
27
|
-
requirement: &
|
27
|
+
requirement: &12956740 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,21 +32,21 @@ dependencies:
|
|
32
32
|
version: 1.6.3
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *12956740
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
|
-
name:
|
38
|
-
requirement: &
|
37
|
+
name: multi_json
|
38
|
+
requirement: &12955960 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
|
-
- -
|
41
|
+
- - ~>
|
42
42
|
- !ruby/object:Gem::Version
|
43
|
-
version: 1.
|
43
|
+
version: 1.1.0
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *12955960
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: rack
|
49
|
-
requirement: &
|
49
|
+
requirement: &12955120 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ! '>='
|
@@ -54,7 +54,7 @@ dependencies:
|
|
54
54
|
version: '1.3'
|
55
55
|
type: :runtime
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *12955120
|
58
58
|
description:
|
59
59
|
email:
|
60
60
|
executables: []
|
@@ -67,18 +67,18 @@ files:
|
|
67
67
|
- CHANGELOG.rdoc
|
68
68
|
- README.md
|
69
69
|
- Rakefile
|
70
|
-
- lib/jimson.rb
|
71
|
-
- lib/jimson/server/error.rb
|
72
|
-
- lib/jimson/handler.rb
|
73
|
-
- lib/jimson/server.rb
|
70
|
+
- lib/jimson/request.rb
|
74
71
|
- lib/jimson/response.rb
|
72
|
+
- lib/jimson/server.rb
|
75
73
|
- lib/jimson/client/error.rb
|
76
|
-
- lib/jimson/request.rb
|
77
74
|
- lib/jimson/client.rb
|
75
|
+
- lib/jimson/handler.rb
|
76
|
+
- lib/jimson/server/error.rb
|
77
|
+
- lib/jimson.rb
|
78
|
+
- spec/spec_helper.rb
|
79
|
+
- spec/client_spec.rb
|
78
80
|
- spec/handler_spec.rb
|
79
81
|
- spec/server_spec.rb
|
80
|
-
- spec/client_spec.rb
|
81
|
-
- spec/spec_helper.rb
|
82
82
|
homepage: http://www.github.com/chriskite/jimson
|
83
83
|
licenses: []
|
84
84
|
post_install_message:
|
@@ -99,12 +99,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
99
99
|
version: '0'
|
100
100
|
requirements: []
|
101
101
|
rubyforge_project:
|
102
|
-
rubygems_version: 1.8.
|
102
|
+
rubygems_version: 1.8.15
|
103
103
|
signing_key:
|
104
104
|
specification_version: 3
|
105
105
|
summary: JSON-RPC 2.0 client and server
|
106
106
|
test_files:
|
107
|
+
- spec/spec_helper.rb
|
108
|
+
- spec/client_spec.rb
|
107
109
|
- spec/handler_spec.rb
|
108
110
|
- spec/server_spec.rb
|
109
|
-
- spec/client_spec.rb
|
110
|
-
- spec/spec_helper.rb
|