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 CHANGED
@@ -1,3 +1,13 @@
1
+ == 0.5.0 / 2012-03-06
2
+
3
+ * Major enhancements
4
+
5
+ * Switch to MultiJson from json gem
6
+
7
+ * Bug fixes
8
+
9
+ * Allow BigNum in 'id' field of request and response
10
+
1
11
  == 0.3.1 / 2011-08-11
2
12
 
3
13
  * Minor enhancements
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.4.0
1
+ 0.5.0
data/lib/jimson/client.rb CHANGED
@@ -1,11 +1,6 @@
1
1
  require 'blankslate'
2
- module Jimson
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 = JSON.parse(resp)
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
- 'jsonrpc' => JSON_RPC_VERSION,
45
- 'method' => method,
46
- 'params' => args,
47
- 'id' => self.class.make_id
48
- }.to_json
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.to_json
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 = JSON.parse(response)
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'
@@ -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.map(&:to_sym)
21
+ (jimson_default_methods - @jimson_excluded_methods + @jimson_exposed_methods).sort
22
22
  end
23
23
 
24
24
  end
@@ -18,7 +18,7 @@ module Jimson
18
18
  end
19
19
 
20
20
  def to_json(*a)
21
- self.to_h.to_json(*a)
21
+ MultiJson.encode(self.to_h)
22
22
  end
23
23
 
24
24
  end
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 'json'
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.to_json
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.to_sym
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 = JSON.parse(post)
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
- 'jsonrpc' => '2.0',
29
- 'method' => 'foo',
30
- 'params' => [1,2,3],
31
- 'id' => 1
32
- }.to_json
33
- response = BOILERPLATE.merge({'result' => 42}).to_json
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
- }.to_json
59
+ })
60
60
  end
61
61
  it "sends a valid JSON-RPC request and returns the result" do
62
- response = BOILERPLATE.merge({'result' => 42}).to_json
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
- {"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
- ].to_json
79
-
80
- response = [
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
- ].to_json
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(:to_s)
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(:hi)
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(:bye)
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(:object_id)
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(:so_exposed)
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.to_json, {'Content-Type' => 'application/json'}
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 = JSON.parse(last_response.body)
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 = JSON.parse(last_response.body)
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 = JSON.parse(last_response.body)
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 = JSON.parse(last_response.body)
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 = JSON.parse(last_response.body)
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
- 'jsonrpc' => '2.0',
182
- 'method' => 'foobar',
183
- 'id' => 1
184
- }.to_json
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 = JSON.parse(last_response.body)
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 = JSON.parse(last_response.body)
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 = JSON.parse(last_response.body)
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 = JSON.parse(last_response.body)
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 = JSON.parse(last_response.body)
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 = JSON.parse(last_response.body)
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 = JSON.parse(last_response.body)
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
@@ -2,6 +2,7 @@ require 'rubygems'
2
2
  $:.unshift(File.dirname(__FILE__) + '/../lib/')
3
3
  require 'jimson/server'
4
4
  require 'jimson/client'
5
- require 'json'
5
+ require 'bundler/setup'
6
+ require 'multi_json'
6
7
 
7
8
  SPEC_URL = 'http://localhost:8999'
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.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: 2011-09-07 00:00:00.000000000Z
12
+ date: 2012-03-06 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: blankslate
16
- requirement: &13756100 !ruby/object:Gem::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: *13756100
24
+ version_requirements: *12957520
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rest-client
27
- requirement: &13755420 !ruby/object:Gem::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: *13755420
35
+ version_requirements: *12956740
36
36
  - !ruby/object:Gem::Dependency
37
- name: json
38
- requirement: &13754820 !ruby/object:Gem::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.5.1
43
+ version: 1.1.0
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *13754820
46
+ version_requirements: *12955960
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rack
49
- requirement: &13754200 !ruby/object:Gem::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: *13754200
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.6
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