jimson 0.4.0 → 0.5.0
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 +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
|
+

|
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
|