saorin 0.1.4 → 0.2.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/lib/saorin/adapters/clients/base.rb +25 -21
- data/lib/saorin/adapters/servers/base.rb +13 -12
- data/lib/saorin/error.rb +21 -10
- data/lib/saorin/request.rb +22 -5
- data/lib/saorin/response.rb +8 -7
- data/lib/saorin/test.rb +128 -0
- data/lib/saorin/utility.rb +15 -0
- data/lib/saorin/version.rb +1 -1
- data/saorin.gemspec +3 -0
- data/server.rb +1 -1
- data/spec/adapter/base_spec.rb +1 -1
- data/spec/adapter/servers/rack_spec.rb +11 -0
- data/spec/adapter/servers/reel_spec.rb +11 -0
- data/spec/request_spec.rb +3 -1
- data/spec/response_spec.rb +25 -18
- data/spec/support/{shared_examples.rb → rpc_call.rb} +4 -53
- data/spec/support/utils.rb +13 -0
- metadata +62 -6
@@ -12,25 +12,22 @@ module Saorin
|
|
12
12
|
def initialize(options = {})
|
13
13
|
end
|
14
14
|
|
15
|
-
def
|
16
|
-
|
15
|
+
def call(method, *args)
|
16
|
+
apply Saorin::Request.new(method, args, :id => seqid!)
|
17
|
+
end
|
18
|
+
|
19
|
+
def notify(method, *args)
|
20
|
+
apply Saorin::Request.new(method, args)
|
21
|
+
end
|
22
|
+
|
23
|
+
def apply(request)
|
17
24
|
response = send_request request.to_json
|
18
25
|
content = process_response response
|
19
26
|
raise content if content.is_a?(Saorin::RPCError)
|
20
27
|
content
|
21
28
|
end
|
22
29
|
|
23
|
-
|
24
|
-
|
25
|
-
def call_multi(*args)
|
26
|
-
requests = args.map do |arg|
|
27
|
-
request_args = arg.to_a.flatten
|
28
|
-
method = request_args.shift
|
29
|
-
Saorin::Request.new method, request_args, seqid!
|
30
|
-
end
|
31
|
-
response = send_request requests.to_json
|
32
|
-
process_response response
|
33
|
-
end
|
30
|
+
protected
|
34
31
|
|
35
32
|
def send_request(content)
|
36
33
|
raise NotImplementedError
|
@@ -39,11 +36,15 @@ module Saorin
|
|
39
36
|
def process_response(content)
|
40
37
|
response = parse_response content
|
41
38
|
if response.is_a?(::Array)
|
42
|
-
response.map { |res|
|
39
|
+
response.map { |res| handle_response res }
|
43
40
|
else
|
44
|
-
|
41
|
+
handle_response response
|
45
42
|
end
|
43
|
+
rescue Saorin::InvalidResponse => e
|
44
|
+
raise e
|
46
45
|
rescue => e
|
46
|
+
p e
|
47
|
+
print e.backtrace.join("\t\n")
|
47
48
|
raise Saorin::InvalidResponse, e.to_s
|
48
49
|
end
|
49
50
|
|
@@ -53,20 +54,23 @@ module Saorin
|
|
53
54
|
raise Saorin::InvalidResponse, e.to_s
|
54
55
|
end
|
55
56
|
|
56
|
-
def to_content(
|
57
|
-
if
|
58
|
-
|
57
|
+
def to_content(response)
|
58
|
+
return nil if response.nil?
|
59
|
+
if response.error?
|
60
|
+
code, message, data = response.error.values_at('code', 'message', 'data')
|
59
61
|
error_class = Saorin.code_to_error code
|
60
|
-
error_class
|
62
|
+
raise Error, 'unknown error code' unless error_class
|
63
|
+
error_class.new message, :code => code, :data => data
|
61
64
|
else
|
62
|
-
|
65
|
+
response.result
|
63
66
|
end
|
64
67
|
end
|
65
68
|
|
66
69
|
def handle_response(hash)
|
70
|
+
return nil if hash.nil?
|
67
71
|
response = Response.from_hash(hash)
|
68
72
|
response.validate
|
69
|
-
response
|
73
|
+
to_content response
|
70
74
|
end
|
71
75
|
|
72
76
|
def seqid
|
@@ -27,7 +27,7 @@ module Saorin
|
|
27
27
|
handle_request(request)
|
28
28
|
end
|
29
29
|
rescue Saorin::Error => e
|
30
|
-
Response.new(
|
30
|
+
Response.new(:error => e)
|
31
31
|
end
|
32
32
|
|
33
33
|
response && MultiJson.dump(response)
|
@@ -43,29 +43,30 @@ module Saorin
|
|
43
43
|
begin
|
44
44
|
request = Request.from_hash(hash)
|
45
45
|
request.validate
|
46
|
-
|
47
|
-
response = Response.new(result, nil, request.id)
|
48
|
-
notify?(hash) ? nil : response
|
46
|
+
dispatch_request_with_trap_notification request
|
49
47
|
rescue Saorin::InvalidRequest => e
|
50
|
-
Response.new(
|
48
|
+
Response.new(:error => e)
|
51
49
|
rescue Saorin::Error => e
|
52
|
-
Response.new(
|
50
|
+
Response.new(:error => e, :id => request.id)
|
53
51
|
rescue Exception => e
|
54
|
-
|
55
|
-
|
52
|
+
options = {:error => Saorin::InternalError.new}
|
53
|
+
options[:id] = request.id if request
|
54
|
+
Response.new(options)
|
56
55
|
end
|
57
56
|
end
|
58
57
|
|
59
|
-
def
|
60
|
-
|
58
|
+
def dispatch_request_with_trap_notification(request)
|
59
|
+
result = dispatch_request request
|
60
|
+
Response.new(:result => result, :id => request.id)
|
61
|
+
ensure
|
62
|
+
return nil if request.notify?
|
61
63
|
end
|
62
64
|
|
63
65
|
def dispatch_request(request)
|
64
66
|
method = request.method.to_s
|
65
67
|
params = request.params || []
|
66
68
|
|
67
|
-
unless @allowed_methods.include?(method) &&
|
68
|
-
@handler.respond_to?(method)
|
69
|
+
unless @allowed_methods.include?(method) && @handler.respond_to?(method)
|
69
70
|
raise Saorin::MethodNotFound
|
70
71
|
end
|
71
72
|
|
data/lib/saorin/error.rb
CHANGED
@@ -5,15 +5,20 @@ module Saorin
|
|
5
5
|
end
|
6
6
|
|
7
7
|
class RPCError < Error
|
8
|
-
attr_reader :code
|
8
|
+
attr_reader :code, :data
|
9
9
|
|
10
|
-
def initialize(
|
11
|
-
@code = code
|
10
|
+
def initialize(message, options = {})
|
12
11
|
super message
|
12
|
+
@code = options[:code]
|
13
|
+
@data = options[:data]
|
13
14
|
end
|
14
15
|
|
15
16
|
def to_h
|
16
|
-
|
17
|
+
h = {}
|
18
|
+
h['code'] = code
|
19
|
+
h['message'] = message
|
20
|
+
h['data'] = data if data
|
21
|
+
h
|
17
22
|
end
|
18
23
|
|
19
24
|
def to_json(*args)
|
@@ -41,23 +46,29 @@ module Saorin
|
|
41
46
|
JSON_RPC_ERRORS.each do |code, name, message|
|
42
47
|
class_eval <<-EOS
|
43
48
|
class #{name} < RPCError
|
44
|
-
def initialize
|
45
|
-
|
49
|
+
def initialize(message = nil, options = {})
|
50
|
+
options[:code] = #{code}
|
51
|
+
super message || '#{message}', options
|
46
52
|
end
|
47
53
|
end
|
48
54
|
EOS
|
49
55
|
end
|
50
56
|
|
51
57
|
class ServerError < RPCError
|
52
|
-
def initialize(
|
53
|
-
|
58
|
+
def initialize(message, options = {})
|
59
|
+
options[:code] ||= -32000
|
60
|
+
super message, options
|
54
61
|
end
|
55
62
|
end
|
56
63
|
|
57
64
|
class << self
|
58
65
|
def code_to_error(code)
|
59
|
-
|
60
|
-
|
66
|
+
if (-32099..-32000).include?(code)
|
67
|
+
ServerError
|
68
|
+
else
|
69
|
+
@map ||= Hash[JSON_RPC_ERRORS.map { |c, n, m| [c, const_get(n)] }]
|
70
|
+
@map[code]
|
71
|
+
end
|
61
72
|
end
|
62
73
|
end
|
63
74
|
|
data/lib/saorin/request.rb
CHANGED
@@ -1,16 +1,22 @@
|
|
1
1
|
require 'saorin'
|
2
2
|
require 'saorin/error'
|
3
|
+
require 'saorin/utility'
|
3
4
|
require 'multi_json'
|
4
5
|
|
5
6
|
module Saorin
|
6
7
|
class Request
|
7
8
|
attr_accessor :version, :method, :params, :id
|
8
9
|
|
9
|
-
def initialize(method, params,
|
10
|
-
@version = version
|
10
|
+
def initialize(method, params, options = {})
|
11
|
+
@version = options[:version] || Saorin::JSON_RPC_VERSION
|
11
12
|
@method = method
|
12
13
|
@params = params
|
13
|
-
@id = id
|
14
|
+
@id = options[:id]
|
15
|
+
@notify = !options.has_key?(:id)
|
16
|
+
end
|
17
|
+
|
18
|
+
def notify?
|
19
|
+
@notify
|
14
20
|
end
|
15
21
|
|
16
22
|
def valid?
|
@@ -33,7 +39,7 @@ module Saorin
|
|
33
39
|
h['jsonrpc'] = @version
|
34
40
|
h['method'] = @method
|
35
41
|
h['params'] = @params if @params && !@params.empty?
|
36
|
-
h['id'] = @id
|
42
|
+
h['id'] = @id unless notify?
|
37
43
|
h
|
38
44
|
end
|
39
45
|
|
@@ -42,9 +48,20 @@ module Saorin
|
|
42
48
|
MultiJson.dump to_h, options
|
43
49
|
end
|
44
50
|
|
51
|
+
def self.symbolized_keys(hash)
|
52
|
+
hash.each do |k, v|
|
53
|
+
if k.is_a? ::String
|
54
|
+
hash[k.to_sym] = v
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
45
59
|
def self.from_hash(hash)
|
46
60
|
raise Saorin::InvalidRequest unless hash.is_a?(::Hash)
|
47
|
-
|
61
|
+
options = hash.dup
|
62
|
+
method = options.delete('method')
|
63
|
+
params = options.delete('params')
|
64
|
+
new method, params, Saorin::Utility.symbolized_keys(options)
|
48
65
|
end
|
49
66
|
end
|
50
67
|
end
|
data/lib/saorin/response.rb
CHANGED
@@ -1,16 +1,17 @@
|
|
1
1
|
require 'saorin'
|
2
2
|
require 'saorin/error'
|
3
|
+
require 'saorin/utility'
|
3
4
|
require 'multi_json'
|
4
5
|
|
5
6
|
module Saorin
|
6
7
|
class Response
|
7
8
|
attr_accessor :version, :result, :error, :id
|
8
9
|
|
9
|
-
def initialize(
|
10
|
-
@version = version
|
11
|
-
@result = result
|
12
|
-
@error = error
|
13
|
-
@id = id
|
10
|
+
def initialize(options = {})
|
11
|
+
@version = options[:version] || Saorin::JSON_RPC_VERSION
|
12
|
+
@result = options[:result]
|
13
|
+
@error = options[:error]
|
14
|
+
@id = options[:id]
|
14
15
|
end
|
15
16
|
|
16
17
|
def error?
|
@@ -20,7 +21,7 @@ module Saorin
|
|
20
21
|
def valid?
|
21
22
|
return false unless !(@result && @error)
|
22
23
|
return false unless [String].any? { |type| @version.is_a? type }
|
23
|
-
return false unless [
|
24
|
+
return false unless [Object].any? { |type| @result.is_a? type }
|
24
25
|
return false unless [Saorin::Error, Hash, NilClass].any? { |type| @error.is_a? type }
|
25
26
|
return false unless [String, Numeric, NilClass].any? { |type| @id.is_a? type }
|
26
27
|
return false unless @version == JSON_RPC_VERSION
|
@@ -47,7 +48,7 @@ module Saorin
|
|
47
48
|
|
48
49
|
def self.from_hash(hash)
|
49
50
|
raise Saorin::InvalidResponse unless hash.is_a?(::Hash)
|
50
|
-
new
|
51
|
+
new Saorin::Utility.symbolized_keys(hash)
|
51
52
|
end
|
52
53
|
end
|
53
54
|
end
|
data/lib/saorin/test.rb
ADDED
@@ -0,0 +1,128 @@
|
|
1
|
+
require 'saorin/server'
|
2
|
+
require 'saorin/client'
|
3
|
+
require 'thread'
|
4
|
+
require 'logger'
|
5
|
+
require 'rspec'
|
6
|
+
|
7
|
+
module Saorin
|
8
|
+
module Test
|
9
|
+
class Handler
|
10
|
+
def identity(value)
|
11
|
+
value
|
12
|
+
end
|
13
|
+
|
14
|
+
def subtract1(a, b)
|
15
|
+
a - b
|
16
|
+
end
|
17
|
+
|
18
|
+
def subtract2(options)
|
19
|
+
options['minuend'] - options['subtrahend']
|
20
|
+
end
|
21
|
+
|
22
|
+
def update(a, b, c, d, e)
|
23
|
+
'OK'
|
24
|
+
end
|
25
|
+
|
26
|
+
def sum(a, b, c)
|
27
|
+
a + b + c
|
28
|
+
end
|
29
|
+
|
30
|
+
def notify_hello(a)
|
31
|
+
'OK'
|
32
|
+
end
|
33
|
+
|
34
|
+
def get_data
|
35
|
+
['hello', 5]
|
36
|
+
end
|
37
|
+
|
38
|
+
def notify_sum(a, b, c)
|
39
|
+
a + b + c
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
HOST = '127.0.0.1'
|
44
|
+
PORT = 45339
|
45
|
+
|
46
|
+
attr_reader :pid
|
47
|
+
attr_reader :server
|
48
|
+
attr_reader :client
|
49
|
+
|
50
|
+
def create_test_server(options = {})
|
51
|
+
@pid = Process.fork do
|
52
|
+
@server = Saorin::Server.start(Handler.new, {
|
53
|
+
:host => HOST,
|
54
|
+
:port => PORT,
|
55
|
+
:Logger => Logger.new('/dev/null'),
|
56
|
+
:AccessLog => [],
|
57
|
+
}.merge(options))
|
58
|
+
end
|
59
|
+
sleep 3
|
60
|
+
end
|
61
|
+
|
62
|
+
def shutdown_test_server
|
63
|
+
Process.kill :INT, @pid
|
64
|
+
sleep 3
|
65
|
+
end
|
66
|
+
|
67
|
+
def create_test_client(options = {})
|
68
|
+
@client = Saorin::Client.new({
|
69
|
+
:url => "http://127.0.0.1:#{PORT}"
|
70
|
+
}.merge(options))
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_call(*args)
|
74
|
+
@client.call *args
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_notify(*args)
|
78
|
+
@client.notify *args
|
79
|
+
end
|
80
|
+
|
81
|
+
shared_context 'setup rpc server client' do
|
82
|
+
let(:server_adapter) {}
|
83
|
+
let(:client_adapter) {}
|
84
|
+
before(:all) do
|
85
|
+
create_test_server :adapter => server_adapter
|
86
|
+
create_test_client :adapter => client_adapter
|
87
|
+
end
|
88
|
+
after(:all) do
|
89
|
+
shutdown_test_server
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
shared_examples 'rpc server client' do
|
94
|
+
it 'string' do
|
95
|
+
value = '123'
|
96
|
+
test_call('identity', value).should eq value
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'number' do
|
100
|
+
value = 123
|
101
|
+
test_call('identity', value).should eq value
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'array' do
|
105
|
+
value = [1, 2, 3]
|
106
|
+
test_call('identity', value).should eq value
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'hash' do
|
110
|
+
value = {'foo' => 1, 'bar' => 2}
|
111
|
+
test_call('identity', value).should eq value
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'nil' do
|
115
|
+
value = nil
|
116
|
+
test_call('identity', value).should eq value
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'not found' do
|
120
|
+
lambda { test_call('xxx') }.should raise_error MethodNotFound
|
121
|
+
end
|
122
|
+
|
123
|
+
it 'invalid params' do
|
124
|
+
lambda { test_call('identity', 1, 2, 3, 4, 5) }.should raise_error InvalidParams
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
data/lib/saorin/version.rb
CHANGED
data/saorin.gemspec
CHANGED
@@ -20,4 +20,7 @@ Gem::Specification.new do |gem|
|
|
20
20
|
gem.add_dependency 'multi_json'
|
21
21
|
gem.add_development_dependency 'rake'
|
22
22
|
gem.add_development_dependency 'rspec'
|
23
|
+
gem.add_development_dependency 'rack'
|
24
|
+
gem.add_development_dependency 'reel'
|
25
|
+
gem.add_development_dependency 'faraday'
|
23
26
|
end
|
data/server.rb
CHANGED
data/spec/adapter/base_spec.rb
CHANGED
@@ -4,7 +4,7 @@ require 'saorin/adapters/servers/base'
|
|
4
4
|
describe Saorin::Adapters::Servers::Base do
|
5
5
|
it_should_behave_like 'rpc call' do
|
6
6
|
let(:process) do
|
7
|
-
handler = Handler.new
|
7
|
+
handler = Saorin::Test::Handler.new
|
8
8
|
server = Saorin::Adapters::Servers::Base.new handler
|
9
9
|
proc do |input|
|
10
10
|
server.process_request input
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'saorin/test'
|
3
|
+
require 'saorin/adapters/servers/rack'
|
4
|
+
|
5
|
+
describe Saorin::Adapters::Servers::Rack do
|
6
|
+
include Saorin::Test
|
7
|
+
|
8
|
+
let(:server_adapter) { :rack }
|
9
|
+
include_context 'setup rpc server client'
|
10
|
+
it_should_behave_like 'rpc server client'
|
11
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'saorin/test'
|
3
|
+
require 'saorin/adapters/servers/reel'
|
4
|
+
|
5
|
+
describe Saorin::Adapters::Servers::Reel do
|
6
|
+
include Saorin::Test
|
7
|
+
|
8
|
+
let(:server_adapter) { :reel }
|
9
|
+
include_context 'setup rpc server client'
|
10
|
+
it_should_behave_like 'rpc server client'
|
11
|
+
end
|
data/spec/request_spec.rb
CHANGED
@@ -9,7 +9,9 @@ describe Saorin::Request do
|
|
9
9
|
:id => rand(1 << 31),
|
10
10
|
}
|
11
11
|
options = default_options.merge(options)
|
12
|
-
|
12
|
+
method = options.delete(:method)
|
13
|
+
params = options.delete(:params)
|
14
|
+
Saorin::Request.new method, params, options
|
13
15
|
end
|
14
16
|
|
15
17
|
describe '#initialize' do
|
data/spec/response_spec.rb
CHANGED
@@ -9,12 +9,12 @@ describe Saorin::Response do
|
|
9
9
|
:id => rand(1 << 31),
|
10
10
|
}
|
11
11
|
options = default_options.merge(options)
|
12
|
-
Saorin::Response.new
|
12
|
+
Saorin::Response.new options
|
13
13
|
end
|
14
14
|
|
15
15
|
describe '#initialize' do
|
16
16
|
context 'success' do
|
17
|
-
before { @r =
|
17
|
+
before { @r = Saorin::Response.new :result => '123', :id => 123 }
|
18
18
|
subject { @r }
|
19
19
|
its(:version) { should eq Saorin::JSON_RPC_VERSION }
|
20
20
|
its(:result) { should eq '123' }
|
@@ -23,10 +23,10 @@ describe Saorin::Response do
|
|
23
23
|
its(:error?) { should be_false }
|
24
24
|
end
|
25
25
|
|
26
|
-
context '
|
26
|
+
context 'error' do
|
27
27
|
before do
|
28
28
|
@e = Saorin::InvalidRequest.new
|
29
|
-
@r =
|
29
|
+
@r = Saorin::Response.new :error => @e, :id => 123
|
30
30
|
end
|
31
31
|
subject { @r }
|
32
32
|
its(:version) { should eq Saorin::JSON_RPC_VERSION }
|
@@ -44,21 +44,28 @@ describe Saorin::Response do
|
|
44
44
|
create_response(:version => 2).should_not be_valid
|
45
45
|
end
|
46
46
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
47
|
+
context 'result' do
|
48
|
+
def create_success_response(result)
|
49
|
+
create_response(:result => result, :error => nil)
|
50
|
+
end
|
51
|
+
|
52
|
+
it('number') { create_success_response(123).should be_valid }
|
53
|
+
it('string') { create_success_response('123').should be_valid }
|
54
|
+
it('nil') { create_success_response(nil).should be_valid }
|
55
|
+
it('array') { create_success_response([]).should be_valid }
|
56
|
+
it('hash') { create_success_response({}).should be_valid }
|
57
|
+
end
|
52
58
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
create_response(:result => nil, :error => {}).should be_valid
|
58
|
-
create_response(:result => nil, :error => Saorin::InvalidResponse.new).should be_valid
|
59
|
+
context 'error' do
|
60
|
+
def create_fail_response(error)
|
61
|
+
create_response(:result => nil, :error => error)
|
62
|
+
end
|
59
63
|
|
60
|
-
|
61
|
-
|
64
|
+
it('number') { create_fail_response(123).should_not be_valid }
|
65
|
+
it('string') { create_fail_response('123').should_not be_valid }
|
66
|
+
it('array') { create_fail_response([]).should_not be_valid }
|
67
|
+
it('hash') { create_fail_response({}).should be_valid }
|
68
|
+
it('exception') { create_fail_response(Saorin::InvalidResponse.new).should be_valid }
|
62
69
|
end
|
63
70
|
|
64
71
|
it 'id' do
|
@@ -95,7 +102,7 @@ describe Saorin::Response do
|
|
95
102
|
h.should_not include('result')
|
96
103
|
h.should include('error')
|
97
104
|
end
|
98
|
-
it '
|
105
|
+
it 'error' do
|
99
106
|
h = create_response(:error => nil).to_h
|
100
107
|
h.should include('result')
|
101
108
|
h.should_not include('error')
|
@@ -1,55 +1,6 @@
|
|
1
|
+
require 'support/utils'
|
1
2
|
require 'json'
|
2
3
|
|
3
|
-
class Handler
|
4
|
-
def subtract1(a, b)
|
5
|
-
a - b
|
6
|
-
end
|
7
|
-
|
8
|
-
def subtract2(options)
|
9
|
-
options['minuend'] - options['subtrahend']
|
10
|
-
end
|
11
|
-
|
12
|
-
def update(a, b, c, d, e)
|
13
|
-
'OK'
|
14
|
-
end
|
15
|
-
|
16
|
-
def foobar1
|
17
|
-
'OK'
|
18
|
-
end
|
19
|
-
|
20
|
-
def foobar3(a, b)
|
21
|
-
'OK'
|
22
|
-
end
|
23
|
-
|
24
|
-
def sum(a, b, c)
|
25
|
-
a + b + c
|
26
|
-
end
|
27
|
-
|
28
|
-
def notify_hello(a)
|
29
|
-
'OK'
|
30
|
-
end
|
31
|
-
|
32
|
-
def get_data
|
33
|
-
['hello', 5]
|
34
|
-
end
|
35
|
-
|
36
|
-
def notify_sum(a, b, c)
|
37
|
-
a + b + c
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
def deserialize(data)
|
42
|
-
data && JSON.load(data)
|
43
|
-
end
|
44
|
-
|
45
|
-
def validates(process, inputs, answers)
|
46
|
-
inputs.zip(answers).each do |input, answer|
|
47
|
-
output = deserialize process.call(input)
|
48
|
-
answer = deserialize answer
|
49
|
-
output.should eq answer
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
4
|
shared_examples 'rpc call with positional parameters' do
|
54
5
|
it 'rpc call with positional parameters' do
|
55
6
|
inputs << %({"jsonrpc": "2.0", "method": "subtract1", "params": [42, 23], "id": 1})
|
@@ -74,7 +25,7 @@ shared_examples 'a Notification' do
|
|
74
25
|
it 'a Notification' do
|
75
26
|
inputs << %({"jsonrpc": "2.0", "method": "update", "params": [1,2,3,4,5]})
|
76
27
|
answers << nil
|
77
|
-
inputs << %({"jsonrpc": "2.0", "method": "
|
28
|
+
inputs << %({"jsonrpc": "2.0", "method": "foobar"})
|
78
29
|
answers << nil
|
79
30
|
validates process, inputs, answers
|
80
31
|
end
|
@@ -82,7 +33,7 @@ end
|
|
82
33
|
|
83
34
|
shared_examples 'rpc call of non-existent method' do
|
84
35
|
it 'rpc call of non-existent method' do
|
85
|
-
inputs << %({"jsonrpc": "2.0", "method": "
|
36
|
+
inputs << %({"jsonrpc": "2.0", "method": "foobar", "id": "1"})
|
86
37
|
answers << %({"jsonrpc": "2.0", "error": {"code": -32601, "message": "Method not found"}, "id": "1"})
|
87
38
|
validates process, inputs, answers
|
88
39
|
end
|
@@ -90,7 +41,7 @@ end
|
|
90
41
|
|
91
42
|
shared_examples 'rpc call with invalid JSON' do
|
92
43
|
it 'rpc call with invalid JSON' do
|
93
|
-
inputs << %({"jsonrpc": "2.0", "method": "
|
44
|
+
inputs << %({"jsonrpc": "2.0", "method": "foobar, "params": "bar", "baz])
|
94
45
|
answers << %({"jsonrpc": "2.0", "error": {"code": -32700, "message": "Parse error"}, "id": null})
|
95
46
|
validates process, inputs, answers
|
96
47
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'saorin/test'
|
2
|
+
|
3
|
+
def deserialize(data)
|
4
|
+
data && JSON.load(data)
|
5
|
+
end
|
6
|
+
|
7
|
+
def validates(process, inputs, answers)
|
8
|
+
inputs.zip(answers).each do |input, answer|
|
9
|
+
output = deserialize process.call(input)
|
10
|
+
answer = deserialize answer
|
11
|
+
output.should eq answer
|
12
|
+
end
|
13
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: saorin
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-03-
|
12
|
+
date: 2013-03-09 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: multi_json
|
@@ -59,6 +59,54 @@ dependencies:
|
|
59
59
|
- - ! '>='
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: rack
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: reel
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: faraday
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
62
110
|
description: JSON-RPC 2.0 implementation
|
63
111
|
email:
|
64
112
|
- mail@mashiro.org
|
@@ -87,14 +135,19 @@ files:
|
|
87
135
|
- lib/saorin/request.rb
|
88
136
|
- lib/saorin/response.rb
|
89
137
|
- lib/saorin/server.rb
|
138
|
+
- lib/saorin/test.rb
|
139
|
+
- lib/saorin/utility.rb
|
90
140
|
- lib/saorin/version.rb
|
91
141
|
- saorin.gemspec
|
92
142
|
- server.rb
|
93
143
|
- spec/adapter/base_spec.rb
|
144
|
+
- spec/adapter/servers/rack_spec.rb
|
145
|
+
- spec/adapter/servers/reel_spec.rb
|
94
146
|
- spec/request_spec.rb
|
95
147
|
- spec/response_spec.rb
|
96
148
|
- spec/spec_helper.rb
|
97
|
-
- spec/support/
|
149
|
+
- spec/support/rpc_call.rb
|
150
|
+
- spec/support/utils.rb
|
98
151
|
homepage: ''
|
99
152
|
licenses: []
|
100
153
|
post_install_message:
|
@@ -109,7 +162,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
109
162
|
version: '0'
|
110
163
|
segments:
|
111
164
|
- 0
|
112
|
-
hash:
|
165
|
+
hash: -2145368172034945708
|
113
166
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
114
167
|
none: false
|
115
168
|
requirements:
|
@@ -118,7 +171,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
118
171
|
version: '0'
|
119
172
|
segments:
|
120
173
|
- 0
|
121
|
-
hash:
|
174
|
+
hash: -2145368172034945708
|
122
175
|
requirements: []
|
123
176
|
rubyforge_project:
|
124
177
|
rubygems_version: 1.8.24
|
@@ -127,7 +180,10 @@ specification_version: 3
|
|
127
180
|
summary: JSON-RPC 2.0 server and client implementation for any protocols
|
128
181
|
test_files:
|
129
182
|
- spec/adapter/base_spec.rb
|
183
|
+
- spec/adapter/servers/rack_spec.rb
|
184
|
+
- spec/adapter/servers/reel_spec.rb
|
130
185
|
- spec/request_spec.rb
|
131
186
|
- spec/response_spec.rb
|
132
187
|
- spec/spec_helper.rb
|
133
|
-
- spec/support/
|
188
|
+
- spec/support/rpc_call.rb
|
189
|
+
- spec/support/utils.rb
|