json-rpc-client 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 45369d3297682f37bcf9119e27b3756a89ed464c
4
+ data.tar.gz: 9e1d8b669fcb8c51dd814161c7337abf7a7769d0
5
+ SHA512:
6
+ metadata.gz: e5d14d9afa48ab3f7b084d9d435aa081b54b411490b4530b189f27f90fa585942a1cb266b14a93e440656eaa663db528f40e683af47d02c1eb484edc5375a64b
7
+ data.tar.gz: 3c6093337ccce5a371c8115a5ef5ef248869405b5e00a628813d080e48d7d5b9eb3f5db2823ccda06bc4b002168b817a4d6dbd0628f41dc9d29dbeadcd2d90d6
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'bundler'
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,16 @@
1
+ Copyright (C) 2012-2013 Textalk AB
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software
4
+ and associated documentation files (the "Software"), to deal in the Software without restriction,
5
+ including without limitation the rights to use, copy, modify, merge, publish, distribute,
6
+ sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
7
+ furnished to do so, subject to the following conditions:
8
+
9
+ The above copyright notice and this permission notice shall be included in all copies or substantial
10
+ portions of the Software.
11
+
12
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
13
+ NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
14
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
15
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
16
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,87 @@
1
+ Asynchronous (EventMachine) JSON-RPC 2.0 client
2
+ ===============================================
3
+
4
+ This gem is a client implementation for JSON-RPC 2.0. It uses EventMachine to
5
+ enable asynchronous communication with a JSON-RPC server. It can be used synchronously if
6
+ called within a (non-root) fiber.
7
+
8
+ Usage example for asynchronous behaviour:
9
+ ```Ruby
10
+ wallet = JsonRpcClient.new('https://localhost:8332/') # Local bitcoin wallet
11
+ balance_rpc = wallet.getbalance()
12
+ balance_rpc.callback do |result|
13
+ puts result # => 90.12345678
14
+ end
15
+
16
+ balance_rpc.errback do |error|
17
+ puts error
18
+ # => "JsonRpcClient.Error: Bad method, code: -32601, data: nil"
19
+ end
20
+ ```
21
+
22
+ Usage example for synchronous behaviour:
23
+ ```Ruby
24
+ require 'eventmachine'
25
+ require 'json-rpc-client'
26
+ require 'fiber'
27
+
28
+ EventMachine.run do
29
+ # To use the syncing behaviour, use it in a fiber.
30
+ fiber = Fiber.new do
31
+ article = JsonRpcClient.new(
32
+ 'https://shop.textalk.se/backend/jsonrpc/Article/14284660',
33
+ {asynchronous_calls: false}
34
+ )
35
+ puts article.get({name: true})
36
+ # => {:name=>{:sv=>"Presentkort 1000 kr", :en=>"Gift certificate 1000 SEK"}}
37
+
38
+ EventMachine.stop
39
+ end
40
+
41
+ fiber.resume
42
+ end
43
+ ```
44
+
45
+ Logging
46
+ -------
47
+
48
+ The client supports both a default logger (for all instances) and a per instance logger.
49
+ Simply attach a logger of your choice(that responds to info, warning, error and debug) and
50
+ any interaction will be output as debug, and any errors as errors. Any per instance logger will
51
+ override the default logger for that instance.
52
+
53
+ ```Ruby
54
+ require 'logger'
55
+ JsonRpcClient.default_logger = Logger.new($STDOUT)
56
+ wallet = JsonRpcClient.new('https://localhost:8332/') # Local bitcoin wallet
57
+ wallet.logger = MyCustomLogger.new()
58
+ ```
59
+
60
+ Development
61
+ -----------
62
+
63
+ To set up a development environment, simply do:
64
+
65
+ ```bash
66
+ bundle install
67
+ bundle exec rake # run the test suite
68
+ ```
69
+
70
+ There are autotests located in the test folder and the framework used is
71
+ [Bacon](https://github.com/chneukirchen/bacon). They're all mocked with
72
+ [VCR](https://github.com/vcr/vcr)/[Webmock](https://github.com/bblimke/webmock)
73
+ so no internet connection is required to run them.
74
+
75
+ JSON-RPC 2.0
76
+ ------------
77
+
78
+ JSON-RPC 2.0 is a very simple protocol for remote procedure calls,
79
+ agnostic of carrier (http, websocket, tcp, whatever…).
80
+
81
+ [JSON-RPC 2.0 Specification](http://www.jsonrpc.org/specification)
82
+
83
+ Copyright
84
+ ---------
85
+ Copyright (C) 2012-2013, Textalk AB <http://textalk.se/>
86
+
87
+ JSON-RPC client is freely distributable under the terms of an MIT license. See [LICENCE](LICENSE).
@@ -0,0 +1,7 @@
1
+ desc 'Runs the test suite'
2
+ task :test do
3
+ sh "bacon test/json-rpc-test.rb"
4
+ end
5
+
6
+ desc "Run tests"
7
+ task :default => :test
@@ -0,0 +1,261 @@
1
+ require 'em-http-request'
2
+ require 'json'
3
+ require 'addressable/uri'
4
+
5
+ # This implements a client for JSON-RPC (version 2) calls.
6
+ #
7
+ # @example Asynchronous
8
+ # wallet = JsonRpcClient.new('https://localhost:8332/') # Local bitcoin wallet
9
+ # balance_rpc = wallet.getbalance()
10
+ # balance_rpc.callback do |result|
11
+ # puts result # => 90.12345678
12
+ # end
13
+ #
14
+ # balance_rpc.errback do |error|
15
+ # puts error
16
+ # # => "JsonRpcClient.Error: Bad method, code: -32601, data: nil"
17
+ # end
18
+ #
19
+ # @example Synchronous
20
+ # require 'eventmachine'
21
+ # require 'json-rpc-client'
22
+ # require 'fiber'
23
+ #
24
+ # EventMachine.run do
25
+ # # To use the syncing behaviour, use it in a fiber.
26
+ # fiber = Fiber.new do
27
+ # article = JsonRpcClient.new(
28
+ # 'https://shop.textalk.se/backend/jsonrpc/Article/14284660',
29
+ # {asynchronous_calls: false}
30
+ # )
31
+ # puts article.get({name: true})
32
+ # # => {:name=>{:sv=>"Presentkort 1000 kr", :en=>"Gift certificate 1000 SEK"}}
33
+
34
+ # EventMachine.stop
35
+ # end
36
+
37
+ # fiber.resume
38
+ # end
39
+ #
40
+ # @!attribute asynchronous_calls
41
+ # @return [Boolean] If method_missing calls are made asynchronously. Default: true
42
+ # @!attribute symbolize_names
43
+ # @return [Boolean] If the result of sync calls should have the names be symbols. Default: true
44
+ # @!attribute logger
45
+ # @return [Logger] The logger instance attached to the instance of JsonRpcClient.
46
+ # Should accept method calls to debug, info, warning & error. Use JsonRpcClient.log for logging
47
+ class JsonRpcClient
48
+ attr_accessor :asynchronous_calls, :symbolize_names, :logger
49
+
50
+ # Invalid JSON was received by the server.
51
+ # An error occurred on the server while parsing the JSON text.
52
+ INVALID_JSON = -32700
53
+ # The JSON sent is not a valid Request object.
54
+ INVALID_REQUEST = -32600
55
+ # The method does not exist / is not available.
56
+ METHOD_NOT_FOUND = -32601
57
+ # Invalid method parameter(s).
58
+ INVALID_PARAMS = -32602
59
+ # Internal JSON-RPC error.
60
+ INTERNAL_ERROR = -32603
61
+
62
+ # Create an instance to call the RPC methods on.
63
+ #
64
+ # @param [String, Addressable::URI, #to_str] service_uri The URI to connect to.
65
+ # @param [Hash] options Options hash to pass to the instance.
66
+ # See Instance Attribute Details in the documentation for more details on supported options.
67
+ def initialize(service_uri, options = {})
68
+ @uri = Addressable::URI.parse(service_uri)
69
+ @asynchronous_calls = options.has_key?(:asynchronous_calls) ?
70
+ !!options[:asynchronous_calls] :
71
+ true
72
+ @symbolize_names = options.has_key?(:symbolize_names) ? !!options[:symbolize_names] : true
73
+ @logger = options[:logger]
74
+ end
75
+
76
+ # Called whenever the current object receives a method call that it does not respond to.
77
+ # Will make a call asynchronously or synchronously depending on asynchronous_calls.
78
+ #
79
+ # @param [String] method the API method, ie get, set.
80
+ # @param [Array] params the parameters sent with the method call.
81
+ def method_missing(method, *params)
82
+ @asynchronous_calls ? self._call_async(method, params) : self._call_sync(method, params)
83
+ end
84
+
85
+ # Makes the call asynchronously and returns a EM::Deferrable.
86
+ # The underscore is there to avoid conflicts with server methods, not to denote a private method.
87
+ #
88
+ # @param [String] method The API method, ie get, set etc.
89
+ # @param [Array, Hash] params The parameters that should be sent along in the post body.
90
+ # @return [EM::Deferrable] The JsonRpcClient::Request as data.
91
+ def _call_async(method, params)
92
+ return Request.new({
93
+ service_uri: @uri.to_s,
94
+ method: method,
95
+ params: params,
96
+ logger: @logger,
97
+ symbolize_names: @symbolize_names
98
+ });
99
+ end
100
+
101
+ # Make the call synchronously, returns the result directly.
102
+ # The underscore is there to avoid conflicts with server methods, not to denote a private method.
103
+ #
104
+ # @param [String] method The API method, ie get, set etc.
105
+ # @param [Array, Hash] params The parameters that should be sent along in the post body.
106
+ # @return [Hash] The result.
107
+ # @raise JsonRpcClient::Error When the request responds with failed status.
108
+ def _call_sync(method, params)
109
+ f = Fiber.current
110
+
111
+ request = _call_async(method, params)
112
+
113
+ request.callback do |*args|
114
+ # If we happen to be in the calling fiber, return the data directly.
115
+ return args.size == 1 ? args.first : args if f == Fiber.current
116
+ # else, return it to the yield call below (in the correct fiber).
117
+ f.resume(*args)
118
+ end
119
+
120
+ request.errback do |error|
121
+ json_rpc_error = Error.new(error[:message], error[:code], error[:data])
122
+ # If we happen to be in the calling fiber, raise the error directly.
123
+ raise json_rpc_error if f == Fiber.current
124
+ # else, return it to the yield call below (in the correct fiber).
125
+ f.resume(json_rpc_error)
126
+ end
127
+
128
+ begin
129
+ response = Fiber.yield # will yield and return the data or raise the error.
130
+ rescue FiberError
131
+ raise "To to use the syncing behaviour in JsonRpcClient, the call must be in a fiber."
132
+ end
133
+ raise response if response.kind_of?(Error)
134
+ return response
135
+ end
136
+
137
+ # Makes a notify call by just sending a HTTP request and not caring about the response.
138
+ # The underscore is there to avoid conflicts with server methods, not to denote a private method.
139
+ #
140
+ # @param [String] method The API method, ie get, set etc.
141
+ # @param [Array, Hash] params The parameters that should be sent along in the post body.
142
+ def _notify(method, params)
143
+ post_body = {
144
+ method: method,
145
+ params: params,
146
+ jsonrpc: '2.0'
147
+ }.to_json
148
+
149
+
150
+ EM::HttpRequest.new(@uri.to_s).post :body => post_body
151
+ self.class.log(:debug, "NOTIFY: #{@uri.to_s} --> #{post_body}", @logger)
152
+ end
153
+
154
+ # The logger to be used for an instances if they don't have a logger set on that instance.
155
+ @@default_logger = nil
156
+
157
+ # @return The default logger object.
158
+ def self.default_logger()
159
+ @@default_logger
160
+ end
161
+
162
+ # Add a default logging instance, that should accept method calls to debug, info, warning & error.
163
+ # Don't use directly, use self.log.
164
+ def self.default_logger=(logger)
165
+ @@default_logger = logger
166
+ end
167
+
168
+ # Logging class that takes severity and message. Only logs if a logger is attached.
169
+ #
170
+ # @param [Symbol, String] level The severity, ie a method of a logger, (info, debug, warn, error).
171
+ # @param [String] message The log message.
172
+ # @param [Logger] logger An instance of a logger class.
173
+ def self.log(level, message, logger = nil)
174
+ logger = logger || @@default_logger
175
+ logger.send(level.to_sym, message) if logger.respond_to?(level.to_sym)
176
+ end
177
+
178
+ # This class corresponds to the JSON-RPC error object gotten from the server.
179
+ # A "faked" instance of this will be thrown for communication errors as well.
180
+ class Error < RuntimeError
181
+ attr_reader :code, :data
182
+ def initialize(msg, code, data)
183
+ super(msg)
184
+ @code = code
185
+ @data = data
186
+ end
187
+
188
+
189
+ # Returns the contents of the current error object as a string.
190
+ #
191
+ # @return [String]
192
+ def inspect
193
+ %|#{self.class}: #{self.message}, code: #{@code.inspect}, data: #{@data.inspect}|
194
+ end
195
+ end
196
+
197
+ # This class makes a single request to the JSON-RPC service as a EventMachine::Deferrable.
198
+ # The deferrable object will give a successful callback in the result-part of the response.
199
+ # A unsuccessful request will set the deferred status as failed, and will not deliver a result
200
+ # only the JSON-RPC error object as a Hash.
201
+ class Request
202
+ include EM::Deferrable
203
+
204
+ def initialize(params)
205
+ service_uri = params[:service_uri]
206
+ post_body = {
207
+ method: params[:method],
208
+ params: params[:params],
209
+ id: 'jsonrpc',
210
+ jsonrpc: '2.0',
211
+ }.to_json
212
+
213
+ http = EM::HttpRequest.new(service_uri).post :body => post_body
214
+ JsonRpcClient.log(:debug, "NEW REQUEST: #{service_uri} --> #{post_body}", params[:logger])
215
+
216
+ http.callback do |response|
217
+ begin
218
+ resp = JSON.parse(response.response, {symbolize_names: params[:symbolize_names]})
219
+ JsonRpcClient.log(
220
+ :debug,
221
+ "REQUEST FINISH: #{service_uri} METHOD: #{params[:method]} RESULT: #{resp}",
222
+ params[:logger]
223
+ )
224
+
225
+ if resp.has_key?(:error) || resp.has_key?("error")
226
+ JsonRpcClient.log(
227
+ :error,
228
+ "Error in response from #{service_uri}: #{resp[:error]}",
229
+ params[:logger]
230
+ )
231
+ self.set_deferred_status :failed, resp[:error] || resp["error"]
232
+ end
233
+ self.set_deferred_status :succeeded, resp[:result] || resp["result"]
234
+ rescue JSON::ParserError => e
235
+ JsonRpcClient.log(
236
+ :error,
237
+ "Got exception during parsing of #{response}: #{e}",
238
+ params[:logger]
239
+ )
240
+
241
+ # Making an error object in the same style as a JSON RPC error.
242
+ set_deferred_status :failed, {
243
+ code: JsonRpcClient::INVALID_JSON,
244
+ message: e.message,
245
+ data: e
246
+ }
247
+ end
248
+ end
249
+
250
+ http.errback do |response|
251
+ JsonRpcClient.log(:error, "Error in http request: #{response.error}", params[:logger])
252
+ set_deferred_status :failed, {
253
+ code: JsonRpcClient::INVALID_JSON,
254
+ message: response.error
255
+ }
256
+ end
257
+
258
+ self
259
+ end
260
+ end
261
+ end
@@ -0,0 +1,162 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'em-spec/bacon'
3
+ require 'vcr'
4
+ require 'json'
5
+ require File.expand_path(File.dirname(__FILE__) + '/test-helper.rb')
6
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib/json-rpc-client'))
7
+
8
+ # Sets up a eventmachine channel to be able to notify subscribers when a http request has been done
9
+ # With the async nature and with _notify not returning a Deferrable we can't know if it sent
10
+ # Or when it finished it's request, hence why we hook onto after_http_request and use that.
11
+ vcr_channel = EventMachine::Channel.new
12
+
13
+ VCR.configure do |c|
14
+ c.cassette_library_dir = File.expand_path(File.dirname(__FILE__)) + '/vcr_cassettes'
15
+ c.hook_into :webmock
16
+ # After a http request, push a notification in the EM channel with the request and response.
17
+ c.after_http_request do |request, response|
18
+ vcr_channel.push({request: request, response: response})
19
+ end
20
+ end
21
+
22
+ EM.spec_backend = EventMachine::Spec::Bacon
23
+ EM.describe 'json-rpc-test' do
24
+
25
+ should 'Test default logging' do
26
+ VCR.use_cassette('logger-test') do
27
+ custom_logger = CustomLogger.new()
28
+ JsonRpcClient.default_logger = custom_logger
29
+ client = JsonRpcClient.new('https://shop.textalk.se/backend/jsonrpc/Article/12565607')
30
+ (JsonRpcClient.default_logger == custom_logger).should.equal true
31
+ JsonRpcClient.default_logger = nil #cleanup
32
+ end
33
+
34
+ done
35
+ end
36
+
37
+ should 'Make a sucessful sync json-rpc call and recieve symbolized values' do
38
+ VCR.use_cassette('sync-symbolized') do
39
+ client = JsonRpcClient.new(
40
+ 'https://shop.textalk.se/backend/jsonrpc/Article/12565484',
41
+ {asynchronous_calls: false}
42
+ )
43
+ client.logger = CustomLogger.new()
44
+ uid = client.get(uid: true) # Calling method get on RPC backend, only asking for uid
45
+ client.logger.logs[0] == "NEW REQUEST: https://shop.textalk.se/backend/jsonrpc/Article/12565484 --> {\"method\":\"get\",\"params\":[{\"uid\":true}],\"id\":\"jsonrpc\",\"jsonrpc\":\"2.0\"}"
46
+ client.logger.logs[1] == "REQUEST FINISH: https://shop.textalk.se/backend/jsonrpc/Article/12565484 METHOD: get RESULT: {:jsonrpc=>\"2.0\", :id=>\"jsonrpc\", :result=>{:uid=>\"12565484\"}}"
47
+ (uid == {uid: "12565484"}).should.equal true
48
+ end
49
+
50
+ done
51
+ end
52
+
53
+ should 'Make a sucessful sync json-rpc call and recieve non-symbolized values' do
54
+ VCR.use_cassette('sync-nonsymbolized') do
55
+ client = JsonRpcClient.new('https://shop.textalk.se/backend/jsonrpc/Article/14284660', {
56
+ asynchronous_calls: false,
57
+ symbolize_names: false
58
+ })
59
+ name = client.get(name: true) # Calling same method, asking for name. Should not symobolize result
60
+ (name == {"name"=>{"sv"=>"Presentkort 1000 kr", "en"=>"Gift certificate 1000 SEK"}}).should.equal true
61
+ end
62
+
63
+ done
64
+ end
65
+
66
+ should 'Make a sucessful async json-rpc call and recieve a JsonRpcClient::Request' do
67
+ VCR.insert_cassette("async")
68
+ client = JsonRpcClient.new('https://shop.textalk.se/backend/jsonrpc/Article/12565605')
69
+ request = client.uid() # Calling a valid uri, should get a request back
70
+ request.is_a?(JsonRpcClient::Request).should.equal true
71
+ request.is_a?(EM::Deferrable).should.equal true
72
+ request.callback do |result|
73
+ result.should.equal "12565605"
74
+ VCR.eject_cassette
75
+ done
76
+ end
77
+ end
78
+
79
+ should 'Make a notify call' do
80
+ VCR.insert_cassette("notify")
81
+ # Subscribe to the EM channel, so that we only after the request do the matching and
82
+ # eject the VCR cassette and end the request.
83
+ subscription = vcr_channel.subscribe do |request_response_hash|
84
+ request = request_response_hash[:request]
85
+ (JSON.parse(request[:body]) == {"method"=>"uid", "params"=>{}, "jsonrpc"=>"2.0"}).should.equal true
86
+ vcr_channel.unsubscribe(subscription) # Unsub from the channel
87
+ VCR.eject_cassette
88
+ done # Exit out of the request
89
+ end
90
+ client = JsonRpcClient.new('https://shop.textalk.se/backend/jsonrpc/Article/12565604')
91
+ client._notify(:uid, {}) # Just shouldn't raise an error, and should hit backend.
92
+ end
93
+
94
+ should 'raise jsonrpcerror on bad response' do
95
+ should.raise(JsonRpcClient::Error) do
96
+ VCR.use_cassette('bad-response') do
97
+ client = JsonRpcClient.new('http://www.google.com/', {asynchronous_calls: false})
98
+ client.dummy() # Calling non-existing method on non-rpc backend.
99
+ end
100
+ end
101
+
102
+ done
103
+ end
104
+
105
+ should 'get an http error and raise jsonrpcerror on bad backend url' do
106
+ should.raise(JsonRpcClient::Error) do
107
+ VCR.use_cassette('weird-url') do
108
+ client = JsonRpcClient.new('http://@ł€®þ.com/', {asynchronous_calls: false})
109
+ client.dummy() # Calling non-existing method on non-rpc backend.
110
+ end
111
+ end
112
+
113
+ done
114
+ end
115
+
116
+ should 'get a jsonrpcerror from the backend' do
117
+ should.raise(JsonRpcClient::Error) do
118
+ VCR.use_cassette('jsonrpcerror-method-missing') do
119
+ client = JsonRpcClient.new(
120
+ 'http://shop.textalk.se/backend/jsonrpc/Foo',
121
+ {asynchronous_calls: false}
122
+ )
123
+ error = client.dummy() # Calling non-existing method on rpc backend.
124
+ end
125
+ end
126
+
127
+ done
128
+ end
129
+
130
+ should 'test the error inspect method' do
131
+ VCR.use_cassette('inspect') do
132
+ begin
133
+ client = JsonRpcClient.new(
134
+ 'http://shop.textalk.se/backend/jsonrpc/Article/12565604',
135
+ {asynchronous_calls: false}
136
+ )
137
+ client.dummy()
138
+ rescue JsonRpcClient::Error => e
139
+ e.inspect.should.equal "JsonRpcClient::Error: Method not found: dummy, code: -32601, data: nil"
140
+ end
141
+ end
142
+
143
+ done
144
+ end
145
+ end
146
+
147
+ describe 'Non-fiber' do
148
+
149
+ should 'raise an error about no fibers being used' do
150
+ VCR.use_cassette('non-fiber') do
151
+ should.raise(RuntimeError) do
152
+ EM.run do
153
+ client = JsonRpcClient.new(
154
+ 'http://shop.textalk.se/backend/jsonrpc/Article/12565604',
155
+ {asynchronous_calls: false}
156
+ )
157
+ client.get()
158
+ end
159
+ end
160
+ end
161
+ end
162
+ end
@@ -0,0 +1,23 @@
1
+ require 'simplecov'
2
+ require 'simplecov-rcov'
3
+ require 'logger'
4
+
5
+ SimpleCov.formatter = SimpleCov::Formatter::RcovFormatter
6
+ SimpleCov.command_name 'bacon'
7
+ SimpleCov.start
8
+
9
+ # A small custom logger for the tests, all log messages are saved to an array.
10
+ class CustomLogger < Logger
11
+ attr_reader :logs
12
+ def initialize()
13
+ @logs = []
14
+ end
15
+
16
+ def debug(message)
17
+ @logs << message
18
+ end
19
+
20
+ def error(message)
21
+ @logs << message
22
+ end
23
+ end
metadata ADDED
@@ -0,0 +1,207 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: json-rpc-client
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Fredrik Liljegren
8
+ - Lars Olsson
9
+ - Denis Dervisevic
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2013-04-18 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: addressable
17
+ requirement: !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - - '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - '>='
27
+ - !ruby/object:Gem::Version
28
+ version: '0'
29
+ - !ruby/object:Gem::Dependency
30
+ name: em-http-request
31
+ requirement: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - '>='
34
+ - !ruby/object:Gem::Version
35
+ version: '0'
36
+ type: :runtime
37
+ prerelease: false
38
+ version_requirements: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - '>='
41
+ - !ruby/object:Gem::Version
42
+ version: '0'
43
+ - !ruby/object:Gem::Dependency
44
+ name: json
45
+ requirement: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - '>='
48
+ - !ruby/object:Gem::Version
49
+ version: '0'
50
+ type: :runtime
51
+ prerelease: false
52
+ version_requirements: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - '>='
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ - !ruby/object:Gem::Dependency
58
+ name: bacon
59
+ requirement: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - '>='
62
+ - !ruby/object:Gem::Version
63
+ version: '0'
64
+ type: :development
65
+ prerelease: false
66
+ version_requirements: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - '>='
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ - !ruby/object:Gem::Dependency
72
+ name: em-spec
73
+ requirement: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ type: :development
79
+ prerelease: false
80
+ version_requirements: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - '>='
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
85
+ - !ruby/object:Gem::Dependency
86
+ name: rack
87
+ requirement: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - '>='
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
92
+ type: :development
93
+ prerelease: false
94
+ version_requirements: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ - !ruby/object:Gem::Dependency
100
+ name: rake
101
+ requirement: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - '>='
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ type: :development
107
+ prerelease: false
108
+ version_requirements: !ruby/object:Gem::Requirement
109
+ requirements:
110
+ - - '>='
111
+ - !ruby/object:Gem::Version
112
+ version: '0'
113
+ - !ruby/object:Gem::Dependency
114
+ name: simplecov
115
+ requirement: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - '>='
118
+ - !ruby/object:Gem::Version
119
+ version: '0'
120
+ type: :development
121
+ prerelease: false
122
+ version_requirements: !ruby/object:Gem::Requirement
123
+ requirements:
124
+ - - '>='
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
127
+ - !ruby/object:Gem::Dependency
128
+ name: simplecov-rcov
129
+ requirement: !ruby/object:Gem::Requirement
130
+ requirements:
131
+ - - '>='
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ type: :development
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ requirements:
138
+ - - '>='
139
+ - !ruby/object:Gem::Version
140
+ version: '0'
141
+ - !ruby/object:Gem::Dependency
142
+ name: vcr
143
+ requirement: !ruby/object:Gem::Requirement
144
+ requirements:
145
+ - - '>='
146
+ - !ruby/object:Gem::Version
147
+ version: '0'
148
+ type: :development
149
+ prerelease: false
150
+ version_requirements: !ruby/object:Gem::Requirement
151
+ requirements:
152
+ - - '>='
153
+ - !ruby/object:Gem::Version
154
+ version: '0'
155
+ - !ruby/object:Gem::Dependency
156
+ name: webmock
157
+ requirement: !ruby/object:Gem::Requirement
158
+ requirements:
159
+ - - '='
160
+ - !ruby/object:Gem::Version
161
+ version: 1.9.0
162
+ type: :development
163
+ prerelease: false
164
+ version_requirements: !ruby/object:Gem::Requirement
165
+ requirements:
166
+ - - '='
167
+ - !ruby/object:Gem::Version
168
+ version: 1.9.0
169
+ description: Asynchronous (EventMachine) JSON-RPC 2.0 over HTTP client.
170
+ email:
171
+ executables: []
172
+ extensions: []
173
+ extra_rdoc_files: []
174
+ files:
175
+ - lib/json-rpc-client.rb
176
+ - Gemfile
177
+ - LICENSE
178
+ - README.md
179
+ - Rakefile
180
+ - test/json-rpc-test.rb
181
+ - test/test-helper.rb
182
+ homepage: https://github.com/Textalk/json-rpc-client-ruby
183
+ licenses:
184
+ - MIT
185
+ metadata: {}
186
+ post_install_message:
187
+ rdoc_options: []
188
+ require_paths:
189
+ - lib
190
+ required_ruby_version: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - '>='
193
+ - !ruby/object:Gem::Version
194
+ version: 1.9.0
195
+ required_rubygems_version: !ruby/object:Gem::Requirement
196
+ requirements:
197
+ - - '>='
198
+ - !ruby/object:Gem::Version
199
+ version: '0'
200
+ requirements: []
201
+ rubyforge_project:
202
+ rubygems_version: 2.0.3
203
+ signing_key:
204
+ specification_version: 4
205
+ summary: JSON-RPC 2.0 client.
206
+ test_files: []
207
+ has_rdoc: