rubarb 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,26 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+ require 'rubarb/id'
3
+
4
+ include Rubarb
5
+
6
+ describe Id do
7
+
8
+ before(:each) do
9
+ @id = Id.new
10
+ end
11
+
12
+ it "starts generator at 00000001" do
13
+ @id.next.should == "00000001"
14
+ end
15
+
16
+ it "increments counter by 1 when next is called" do
17
+ @id.next
18
+ @id.next.should == "00000002"
19
+ end
20
+
21
+ it "resets counter to one if id is 99999999" do
22
+ @id.instance_eval{ @id = 99999999 }
23
+ @id.next
24
+ @id.next.should == "00000001"
25
+ end
26
+ end
@@ -0,0 +1,79 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ require "rubarb/incoming_connection"
4
+ require "rubarb/remote_call"
5
+ require "rubarb/default"
6
+
7
+ describe Rubarb::IncomingConnection do
8
+ include Rubarb::RemoteCall
9
+ include Rubarb::IncomingConnection
10
+ attr_reader :api
11
+
12
+ class TestApi
13
+ attr_accessor :dodo
14
+ def amethod(responder, dodo)
15
+ @dodo = dodo
16
+ end
17
+ def ==(rhs)
18
+ end
19
+ end
20
+
21
+ before(:each) do
22
+ @api = TestApi.new
23
+ @insecure_methods = Rubarb::Default::INSECURE_METHODS
24
+ end
25
+
26
+ it "should receive message" do
27
+ receive_message(marshal_call("00000001", :amethod, "goo"))
28
+ @api.dodo.should == "goo"
29
+ end
30
+
31
+ it "should receive reply with exception when a non-existent method is called" do
32
+ should_receive(:reply).with do |id, exception|
33
+ id.should == "0"
34
+ exception.message.include?("undefined method").should == true
35
+ end
36
+ receive_message(marshal_call("00000001", :not_a_method, "foo"))
37
+ @api.should_not_receive(:send)
38
+ end
39
+
40
+ def blocks_method_in_receive_message(method)
41
+ @method = method
42
+ should_receive(:reply).with do |id, exception|
43
+ id.should == "0"
44
+ exception.message.should == "Remote client attempts to call method #{@method}, but was denied."
45
+ end
46
+ receive_message(marshal_call("00000001", method, "foo"))
47
+ @api.should_not_receive(:send)
48
+ end
49
+
50
+ it "blocks :== in receive_message" do
51
+ blocks_method_in_receive_message(:==)
52
+ end
53
+
54
+ it "blocks any insecure method in receive_message" do
55
+ Rubarb::Default::INSECURE_METHODS.each do |method|
56
+ blocks_method_in_receive_message(method)
57
+ end
58
+ end
59
+
60
+ it "receives message with id, method, and *args" do
61
+ message = marshal_call("00000001", :amethod, "foo")
62
+ receive_message(message)
63
+ @api.dodo.should == "foo"
64
+ end
65
+
66
+ it "replies message with id and args" do
67
+ message = marshal_call("00000001", :amethod, "foo")
68
+ receive_message(message)
69
+ self.should_receive(:send_message).with(marshal_call(["00000001", "result"]))
70
+ reply("00000001", "result")
71
+ end
72
+
73
+ it "replies message with id 00000002 and args" do
74
+ message = marshal_call("00000002", :amethod, "foo")
75
+ receive_message(message)
76
+ self.should_receive(:send_message).with(marshal_call(["00000002", "result"]))
77
+ reply("00000002", "result")
78
+ end
79
+ end
@@ -0,0 +1,174 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ require 'rubarb/server'
4
+ require 'rubarb/connection'
5
+
6
+ describe "Server to Client communication and response" do
7
+
8
+ class TestClientApi
9
+ def name(responder)
10
+ responder.reply("Doug")
11
+ end
12
+ end
13
+
14
+ before(:each) do
15
+ @reactor = start_reactor
16
+ @server_api = mock("server")
17
+ @client_api = TestClientApi.new
18
+
19
+ @server = Rubarb::Server.new("127.0.0.1", 9441, @server_api)
20
+ @connection = Rubarb::Connection.new("127.0.0.1", 9441, @client_api)
21
+ end
22
+
23
+ after(:each) do
24
+ stop_reactor(@reactor)
25
+ end
26
+
27
+ it "should communicate with the client" do
28
+ @callback_called = false
29
+
30
+ @server.start do |new_client|
31
+ new_client.name do|result|
32
+ result.should == "Doug"
33
+ @callback_called = true
34
+ end
35
+ end
36
+
37
+ @connection.start
38
+
39
+ wait_for {@callback_called}
40
+
41
+ end
42
+
43
+ end
44
+
45
+ describe "Client to Server communication and response" do
46
+ class TestReply
47
+ attr_reader :message
48
+
49
+ def initialize(name)
50
+ @message = "How are you #{name}, my friend?"
51
+ end
52
+ end
53
+
54
+ class TestServerApi
55
+ attr_reader :hi_called
56
+ def hi(responder)
57
+ responder.reply("how are you?")
58
+ @hi_called = true
59
+ end
60
+
61
+ def hello(responder, name)
62
+ responder.reply("how are you #{name}?")
63
+ end
64
+
65
+ def hello_friend(responder, name)
66
+ responder.reply(TestReply.new(name))
67
+ end
68
+
69
+ attr_reader :conn_id
70
+ def save_id(responder)
71
+ @conn_id = responder.conn_id
72
+ responder.reply(nil)
73
+ end
74
+ end
75
+
76
+ before(:each) do
77
+ @reactor = start_reactor
78
+ @server_api = TestServerApi.new
79
+ @client_api = mock("client")
80
+
81
+ @server = Rubarb::Server.new("127.0.0.1", 9441, @server_api)
82
+ @connection = Rubarb::Connection.new("127.0.0.1", 9441, @client_api)
83
+ end
84
+
85
+ after(:each) do
86
+ stop_reactor(@reactor)
87
+ end
88
+
89
+ it "without a callback" do
90
+ @server.start
91
+
92
+ @connection.start do
93
+ @connection.hi
94
+ end
95
+
96
+ wait_for {@server_api.hi_called}
97
+ end
98
+
99
+ it "without parameters" do
100
+ @callback_called = false
101
+ @server.start
102
+
103
+ @connection.start do
104
+ @connection.hi do |response|
105
+ response.should == "how are you?"
106
+ @callback_called = true
107
+ end
108
+ end
109
+
110
+ wait_for {@callback_called}
111
+ end
112
+
113
+ it "with parameters" do
114
+ @callback_called = false
115
+ @server.start
116
+ @connection.start do
117
+ @connection.hello("Doug") do |response|
118
+ @callback_called = true
119
+ response.should == "how are you Doug?"
120
+ end
121
+ end
122
+ wait_for {@callback_called}
123
+ end
124
+
125
+ it "with complex response" do
126
+ @callback_called = false
127
+ @server.start
128
+ @connection.start do
129
+ @connection.hello_friend("Doug") do |response|
130
+ @callback_called = true
131
+ response.message.should == "How are you Doug, my friend?"
132
+ end
133
+ end
134
+
135
+ wait_for {@callback_called}
136
+ end
137
+
138
+ it "can get connection id on connection" do
139
+ @callback_called = false
140
+ @new_connection_id = nil
141
+ @server.start do |new_connection|
142
+ @new_connection_id = new_connection.conn_id
143
+ end
144
+
145
+ @connection.start do
146
+ @connection.save_id do |response|
147
+ @callback_called = true
148
+ end
149
+ end
150
+
151
+ wait_for {@callback_called}
152
+ @server_api.conn_id.should == @new_connection_id
153
+ end
154
+
155
+ it "should close from server side" do
156
+ @server_side_client_proxy = nil
157
+ @server.start do |new_connection|
158
+ @server_side_client_proxy = new_connection
159
+ end
160
+
161
+ @connection.errback do
162
+ @client_side_closed = true
163
+ end
164
+ @connection.start
165
+
166
+ wait_for {!@server_side_client_proxy.nil?}
167
+ @server_side_client_proxy.stop
168
+
169
+ wait_for {@client_side_closed}
170
+ @client_side_closed.should == true
171
+
172
+ end
173
+
174
+ end
@@ -0,0 +1,103 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ require "rubarb/outgoing_connection"
4
+ require "rubarb/remote_call"
5
+
6
+ describe Rubarb::OutgoingConnection do
7
+ include Rubarb::RemoteCall
8
+ include Rubarb::OutgoingConnection
9
+
10
+ before(:each) do
11
+ @callback = {}
12
+ set_id("00000001")
13
+ end
14
+
15
+ def set_id(id)
16
+ id_generator = mock("id")
17
+ id_generator.stub!(:next).and_return(id)
18
+ @msg_id_generator = id_generator
19
+ end
20
+
21
+ it "sets callback" do
22
+ block = Proc.new { puts "Hello" }
23
+ self.should_receive(:send_message)
24
+ remote_call(:amethod, "asdf", &block)
25
+ @callback["00000001"].should == block
26
+ end
27
+
28
+ it "executes callback block when receive_message is called" do
29
+ block = Proc.new do |v|
30
+ @value = v
31
+ end
32
+ should_receive(:send_message)
33
+ remote_call(:amethod, "asdf", &block)
34
+ receive_message(marshal_call("00000001", "value"))
35
+ @value.should == "value"
36
+ end
37
+
38
+ it "does not execute callback block when receive_message is called with an exception" do
39
+ block = Proc.new { puts "Hello" }
40
+ should_receive(:send_message)
41
+ remote_call(:amethod, "asdf", &block)
42
+ should_receive(:call_errbacks)
43
+ @callback.should_not_receive(:call)
44
+ receive_message(marshal_call("00000001", Exception.new))
45
+ end
46
+
47
+ it "saves error message when receive_message is called with an exception" do
48
+ exception = Exception.new("Hello")
49
+ error = nil
50
+ @errbacks = [Proc.new { |e| error = e }]
51
+ block = Proc.new { puts "Hello" }
52
+
53
+ should_receive(:send_message)
54
+ remote_call(:amethod, "asdf", &block)
55
+ stub!(:call_errbacks).and_return(@errbacks.first.call(exception))
56
+ @callback.stub!(:call)
57
+
58
+ receive_message(marshal_call("00000001", exception))
59
+
60
+ error.class.should == Exception
61
+ error.message.should == (exception.message)
62
+ end
63
+
64
+ it "has a message id argument for marshal_call" do
65
+ block = Proc.new { puts "Hello" }
66
+ should_receive(:marshal_call).with("00000001", :amethod, "asdf")
67
+ self.should_receive(:send_message)
68
+ remote_call(:amethod, "asdf", &block)
69
+ end
70
+
71
+ it "generates a message id" do
72
+ set_id("00000002")
73
+ block = Proc.new { puts "Hello" }
74
+ should_receive(:marshal_call).with("00000002", :amethod, "asdf")
75
+ should_receive(:send_message)
76
+ remote_call(:amethod, "asdf", &block)
77
+ end
78
+
79
+ it "pushes callback block to callback hash with id as key" do
80
+ @callback = {}
81
+ set_id("00000001")
82
+ block = Proc.new { puts "Hello" }
83
+ stub!(:send_message)
84
+ remote_call(:amethod, "asdf", &block)
85
+ @callback["00000001"].should == block
86
+ end
87
+
88
+ it "calls the corresponding block with given id" do
89
+ block = mock("block")
90
+ block.should_receive(:call).with("asdf")
91
+ @callback = { "00000002" => block }
92
+ receive_message(marshal_call("00000002", "asdf"))
93
+ end
94
+
95
+ it "removes callback from hash after call" do
96
+ block = mock("block")
97
+ block.should_receive(:call).with("asdf")
98
+ @callback = { "00000002" => block }
99
+ receive_message(marshal_call("00000002", "asdf"))
100
+ @callback.should have(0).items
101
+ end
102
+
103
+ end
@@ -0,0 +1,48 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ require 'rubarb/remote_call'
4
+ describe Rubarb::RemoteCall do
5
+ include Rubarb::RemoteCall
6
+
7
+ it "should marshal a call" do
8
+ identity_test(:foo, "barr", "none")
9
+ end
10
+
11
+ it "should marshal with no args" do
12
+ identity_test(:food)
13
+ end
14
+
15
+ it "should work with multiple return values" do
16
+ serialized = marshal_call(:eat, "potatos", "carrots")
17
+ recovered_method, arg1, arg2 = unmarshal_call(serialized)
18
+ recovered_method.should == :eat
19
+ arg1.should == "potatos"
20
+ arg2.should == "carrots"
21
+ end
22
+
23
+ class Wine
24
+ attr_accessor :age, :content
25
+ def initialize(age, content)
26
+ @age = age
27
+ @content = content
28
+ end
29
+
30
+ def ==(other)
31
+ return false unless self.age == other.age
32
+ return false unless self.content == other.content
33
+ return true
34
+ end
35
+ end
36
+
37
+ it "should handle complexy objects" do
38
+ identity_test(:make_grapes, Wine.new(15, 0.15), "grapes")
39
+ end
40
+
41
+ def identity_test(method, *args)
42
+ serialized = marshal_call(method, *args)
43
+ recovered_method, *recovered_args = unmarshal_call(serialized)
44
+ recovered_method.should == method
45
+ recovered_args.should == args
46
+ end
47
+
48
+ end
@@ -0,0 +1,35 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+ require "rubarb/responder"
3
+ require "rubarb/incoming_connection"
4
+ require "rubarb/server"
5
+
6
+ include Rubarb
7
+
8
+ class MockHandler
9
+ include Listener
10
+ include IncomingConnection
11
+ end
12
+
13
+ describe Responder do
14
+ before(:each) do
15
+ @responder = Responder.new(MockHandler.new, "00000001")
16
+ end
17
+
18
+ it "sets id on initialize" do
19
+ @responder.message_id.should == "00000001"
20
+ end
21
+
22
+ it "sets handler on initialize" do
23
+ @responder.handler.class.should == MockHandler
24
+ end
25
+
26
+ it "calls handler#reply with stored message_id" do
27
+ @responder.handler.should_receive(:reply).with("00000001", "Hello Doug")
28
+ @responder.reply("Hello Doug")
29
+ end
30
+
31
+ it "calls handler's conn_id" do
32
+ @responder.handler.should_receive(:conn_id)
33
+ @responder.conn_id
34
+ end
35
+ end