librevox 0.9 → 1.0.0.alpha2
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.
- checksums.yaml +5 -5
- data/README.md +252 -167
- data/lib/librevox/applications.rb +80 -67
- data/lib/librevox/client.rb +39 -0
- data/lib/librevox/command_socket.rb +12 -26
- data/lib/librevox/commands.rb +23 -23
- data/lib/librevox/listener/base.rb +49 -30
- data/lib/librevox/listener/inbound.rb +40 -15
- data/lib/librevox/listener/outbound.rb +40 -34
- data/lib/librevox/protocol/connection.rb +47 -0
- data/lib/librevox/protocol/response.rb +60 -0
- data/lib/librevox/runner.rb +37 -0
- data/lib/librevox/server.rb +33 -0
- data/lib/librevox/version.rb +5 -0
- data/lib/librevox.rb +32 -42
- metadata +66 -36
- data/Rakefile +0 -6
- data/TODO +0 -29
- data/lib/librevox/response.rb +0 -52
- data/librevox.gemspec +0 -37
- data/spec/helper.rb +0 -86
- data/spec/librevox/listener/spec_inbound.rb +0 -22
- data/spec/librevox/listener/spec_outbound.rb +0 -300
- data/spec/librevox/listener.rb +0 -142
- data/spec/librevox/spec_applications.rb +0 -238
- data/spec/librevox/spec_commands.rb +0 -103
- data/spec/librevox/spec_response.rb +0 -67
data/lib/librevox/response.rb
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
require 'eventmachine'
|
|
2
|
-
require 'em/protocols/header_and_content'
|
|
3
|
-
|
|
4
|
-
class String
|
|
5
|
-
alias :each :each_line
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
module Librevox
|
|
9
|
-
class Response
|
|
10
|
-
attr_accessor :headers, :content
|
|
11
|
-
|
|
12
|
-
def initialize headers="", content=""
|
|
13
|
-
self.headers = headers
|
|
14
|
-
self.content = content
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def headers= headers
|
|
18
|
-
@headers = headers_2_hash(headers)
|
|
19
|
-
@headers.each {|k,v| v.chomp! if v.is_a?(String)}
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def content= content
|
|
23
|
-
@content = if content.respond_to?(:match) && content.match(/:/)
|
|
24
|
-
headers_2_hash(content).merge(:body => content.split("\n\n", 2)[1].to_s)
|
|
25
|
-
else
|
|
26
|
-
content
|
|
27
|
-
end
|
|
28
|
-
@content.each {|k,v| v.chomp! if v.is_a?(String)}
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def event?
|
|
32
|
-
@content.is_a?(Hash) && @content.include?(:event_name)
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def event
|
|
36
|
-
@content[:event_name] if event?
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def api_response?
|
|
40
|
-
@headers[:content_type] == "api/response"
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
def command_reply?
|
|
44
|
-
@headers[:content_type] == "command/reply"
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
private
|
|
48
|
-
def headers_2_hash *args
|
|
49
|
-
EM::Protocols::HeaderAndContentProtocol.headers_2_hash *args
|
|
50
|
-
end
|
|
51
|
-
end
|
|
52
|
-
end
|
data/librevox.gemspec
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
Gem::Specification.new do |s|
|
|
2
|
-
s.name = "librevox"
|
|
3
|
-
s.version = "0.9"
|
|
4
|
-
s.date = "2014-04-03"
|
|
5
|
-
s.summary = "Ruby library for interacting with FreeSWITCH."
|
|
6
|
-
s.email = "harry@vangberg.name"
|
|
7
|
-
s.homepage = "http://github.com/vangberg/librevox"
|
|
8
|
-
s.description = "EventMachine-based Ruby library for interacting with the
|
|
9
|
-
open source telephony platform FreeSwitch."
|
|
10
|
-
s.authors = ["Harry Vangberg"]
|
|
11
|
-
s.files = [
|
|
12
|
-
"README.md",
|
|
13
|
-
"LICENSE",
|
|
14
|
-
"TODO",
|
|
15
|
-
"Rakefile",
|
|
16
|
-
"librevox.gemspec",
|
|
17
|
-
"lib/librevox.rb",
|
|
18
|
-
"lib/librevox/applications.rb",
|
|
19
|
-
"lib/librevox/command_socket.rb",
|
|
20
|
-
"lib/librevox/commands.rb",
|
|
21
|
-
"lib/librevox/response.rb",
|
|
22
|
-
"lib/librevox/listener/base.rb",
|
|
23
|
-
"lib/librevox/listener/inbound.rb",
|
|
24
|
-
"lib/librevox/listener/outbound.rb"
|
|
25
|
-
]
|
|
26
|
-
s.test_files = [
|
|
27
|
-
"spec/helper.rb",
|
|
28
|
-
"spec/librevox/listener.rb",
|
|
29
|
-
"spec/librevox/spec_applications.rb",
|
|
30
|
-
#"spec/librevox/spec_command_socket.rb",
|
|
31
|
-
"spec/librevox/spec_commands.rb",
|
|
32
|
-
"spec/librevox/spec_response.rb",
|
|
33
|
-
"spec/librevox/listener/spec_inbound.rb",
|
|
34
|
-
"spec/librevox/listener/spec_outbound.rb"
|
|
35
|
-
]
|
|
36
|
-
s.add_dependency "eventmachine", "~> 1.0"
|
|
37
|
-
end
|
data/spec/helper.rb
DELETED
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
require 'bacon'
|
|
2
|
-
require 'librevox'
|
|
3
|
-
|
|
4
|
-
module Librevox::Test
|
|
5
|
-
module Matchers
|
|
6
|
-
def send_command command
|
|
7
|
-
proc {|obj|
|
|
8
|
-
obj.outgoing_data.shift.should == "#{command}\n\n"
|
|
9
|
-
}
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def send_nothing
|
|
13
|
-
proc {|obj| obj.outgoing_data.shift.should == nil}
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def send_application app, args=nil
|
|
17
|
-
proc {|obj|
|
|
18
|
-
msg = <<-EOM
|
|
19
|
-
sendmsg
|
|
20
|
-
call-command: execute
|
|
21
|
-
execute-app-name: #{app}
|
|
22
|
-
EOM
|
|
23
|
-
msg << "execute-app-arg: #{args}\n" if args
|
|
24
|
-
msg << "\n"
|
|
25
|
-
|
|
26
|
-
obj.outgoing_data.shift.should == msg
|
|
27
|
-
}
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def update_session session_id=nil
|
|
31
|
-
if session_id
|
|
32
|
-
proc {|obj|
|
|
33
|
-
obj.outgoing_data.shift.should == "api uuid_dump #{session_id}\n\n"
|
|
34
|
-
}
|
|
35
|
-
else
|
|
36
|
-
proc {|obj|
|
|
37
|
-
obj.outgoing_data.shift.should.match /^api uuid_dump \d+/
|
|
38
|
-
}
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
module ListenerHelpers
|
|
44
|
-
def command_reply args={}
|
|
45
|
-
args["Content-Type"] = "command/reply"
|
|
46
|
-
response args
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def api_response args={}
|
|
50
|
-
args["Content-Type"] = "api/response"
|
|
51
|
-
response args
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
def channel_data args={}
|
|
55
|
-
api_response :body => {
|
|
56
|
-
"Event-Name" => "CHANNEL_DATA",
|
|
57
|
-
"Session-Var" => "Second"
|
|
58
|
-
}.merge(args)
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
def response args={}
|
|
62
|
-
body = args.delete :body
|
|
63
|
-
headers = args
|
|
64
|
-
|
|
65
|
-
if body.is_a? Hash
|
|
66
|
-
body = body.map {|k,v| "#{k}: #{v}"}.join "\n"
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
headers["Content-Length"] = body.size if body
|
|
70
|
-
msg = headers.map {|k, v| "#{k}: #{v}"}.join "\n"
|
|
71
|
-
|
|
72
|
-
msg << "\n\n" + body if body
|
|
73
|
-
|
|
74
|
-
@listener.receive_data msg + "\n\n"
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
def event name
|
|
78
|
-
body = "Event-Name: #{name}"
|
|
79
|
-
headers = "Content-Length: #{body.size}"
|
|
80
|
-
|
|
81
|
-
@listener.receive_data "#{headers}\n\n#{body}\n\n"
|
|
82
|
-
end
|
|
83
|
-
end
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
Bacon.summary_on_exit
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
require './spec/helper'
|
|
2
|
-
require './spec/librevox/listener'
|
|
3
|
-
|
|
4
|
-
require 'librevox/listener/inbound'
|
|
5
|
-
|
|
6
|
-
class InboundTestListener < Librevox::Listener::Inbound
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
describe "Inbound listener" do
|
|
10
|
-
before do
|
|
11
|
-
@listener = InboundTestListener.new(nil)
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
behaves_like "events"
|
|
15
|
-
behaves_like "api commands"
|
|
16
|
-
|
|
17
|
-
should "authorize and subscribe to events" do
|
|
18
|
-
@listener.connection_completed
|
|
19
|
-
@listener.outgoing_data.shift.should == "auth ClueCon\n\n"
|
|
20
|
-
@listener.outgoing_data.shift.should == "event plain ALL\n\n"
|
|
21
|
-
end
|
|
22
|
-
end
|
|
@@ -1,300 +0,0 @@
|
|
|
1
|
-
require './spec/helper'
|
|
2
|
-
require './spec/librevox/listener'
|
|
3
|
-
|
|
4
|
-
require 'librevox/listener/outbound'
|
|
5
|
-
|
|
6
|
-
module Librevox::Applications
|
|
7
|
-
def sample_app name, *args, &block
|
|
8
|
-
application name, args.join(" "), &block
|
|
9
|
-
end
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
class OutboundTestListener < Librevox::Listener::Outbound
|
|
13
|
-
def session_initiated
|
|
14
|
-
send_data "session was initiated"
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def event_and_linger_replies
|
|
19
|
-
command_reply "Reply-Text" => "+OK Events Enabled"
|
|
20
|
-
command_reply "Reply-Text" => "+OK will linger"
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
describe "Outbound listener" do
|
|
24
|
-
extend Librevox::Test::Matchers
|
|
25
|
-
|
|
26
|
-
before do
|
|
27
|
-
@listener = OutboundTestListener.new(nil)
|
|
28
|
-
command_reply(
|
|
29
|
-
"Caller-Caller-Id-Number" => "8675309",
|
|
30
|
-
"Unique-ID" => "1234",
|
|
31
|
-
"variable_some_var" => "some value"
|
|
32
|
-
)
|
|
33
|
-
event_and_linger_replies
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
should "connect to freeswitch and subscribe to events" do
|
|
37
|
-
@listener.should send_command "connect"
|
|
38
|
-
@listener.should send_command "myevents"
|
|
39
|
-
@listener.should send_command "linger"
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
should "establish a session" do
|
|
43
|
-
@listener.session.class.should.equal Hash
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
should "call session callback after establishing new session" do
|
|
47
|
-
@listener.outgoing_data.pop.should == "session was initiated"
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
should "make headers available through session" do
|
|
51
|
-
@listener.session[:caller_caller_id_number].should.equal "8675309"
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
should "make channel variables available through #variable" do
|
|
55
|
-
@listener.variable(:some_var).should == "some value"
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
behaves_like "events"
|
|
59
|
-
behaves_like "api commands"
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
class OutboundListenerWithNestedApps < Librevox::Listener::Outbound
|
|
63
|
-
def session_initiated
|
|
64
|
-
sample_app "foo" do
|
|
65
|
-
sample_app "bar"
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
describe "Outbound listener with apps" do
|
|
71
|
-
extend Librevox::Test::Matchers
|
|
72
|
-
|
|
73
|
-
before do
|
|
74
|
-
@listener = OutboundListenerWithNestedApps.new(nil)
|
|
75
|
-
|
|
76
|
-
command_reply "Establish-Session" => "OK",
|
|
77
|
-
"Unique-ID" => "1234"
|
|
78
|
-
event_and_linger_replies
|
|
79
|
-
3.times {@listener.outgoing_data.shift}
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
should "only send one app at a time" do
|
|
83
|
-
@listener.should send_application "foo"
|
|
84
|
-
@listener.should send_nothing
|
|
85
|
-
|
|
86
|
-
command_reply "Reply-Text" => "+OK"
|
|
87
|
-
@listener.should update_session
|
|
88
|
-
channel_data
|
|
89
|
-
|
|
90
|
-
@listener.should send_application "bar"
|
|
91
|
-
@listener.should send_nothing
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
should "not be driven forward by events" do
|
|
95
|
-
@listener.should send_application "foo"
|
|
96
|
-
|
|
97
|
-
command_reply :body => {
|
|
98
|
-
"Event-Name" => "CHANNEL_EXECUTE",
|
|
99
|
-
"Session-Var" => "Some"
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
@listener.should send_nothing
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
should "not be driven forward by api responses" do
|
|
106
|
-
@listener.should send_application "foo"
|
|
107
|
-
|
|
108
|
-
api_response :body => "Foo"
|
|
109
|
-
|
|
110
|
-
@listener.should send_nothing
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
should "not be driven forward by disconnect notifications" do
|
|
114
|
-
@listener.should send_application "foo"
|
|
115
|
-
|
|
116
|
-
response "Content-Type" => "text/disconnect-notice",
|
|
117
|
-
:body => "Lingering"
|
|
118
|
-
|
|
119
|
-
@listener.should send_nothing
|
|
120
|
-
end
|
|
121
|
-
end
|
|
122
|
-
|
|
123
|
-
module Librevox::Applications
|
|
124
|
-
def reader_app &block
|
|
125
|
-
application 'reader_app', "", {:variable => 'app_var'}, &block
|
|
126
|
-
end
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
class OutboundListenerWithReader < Librevox::Listener::Outbound
|
|
130
|
-
def session_initiated
|
|
131
|
-
reader_app do |data|
|
|
132
|
-
application "send", data
|
|
133
|
-
end
|
|
134
|
-
end
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
describe "Outbound listener with app reading data" do
|
|
138
|
-
extend Librevox::Test::Matchers
|
|
139
|
-
|
|
140
|
-
before do
|
|
141
|
-
@listener = OutboundListenerWithReader.new(nil)
|
|
142
|
-
|
|
143
|
-
command_reply "Session-Var" => "First",
|
|
144
|
-
"Unique-ID" => "1234"
|
|
145
|
-
event_and_linger_replies
|
|
146
|
-
3.times {@listener.outgoing_data.shift}
|
|
147
|
-
|
|
148
|
-
@listener.should send_application "reader_app"
|
|
149
|
-
end
|
|
150
|
-
|
|
151
|
-
should "not send anything while missing response" do
|
|
152
|
-
@listener.should send_nothing
|
|
153
|
-
end
|
|
154
|
-
|
|
155
|
-
should "send uuid_dump to get channel var, after getting response" do
|
|
156
|
-
command_reply "Reply-Text" => "+OK"
|
|
157
|
-
@listener.should update_session 1234
|
|
158
|
-
end
|
|
159
|
-
|
|
160
|
-
should "update session with new data" do
|
|
161
|
-
command_reply :body => "+OK"
|
|
162
|
-
|
|
163
|
-
@listener.should update_session 1234
|
|
164
|
-
api_response :body => {
|
|
165
|
-
"Event-Name" => "CHANNEL_DATA",
|
|
166
|
-
"Session-Var" => "Second"
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
@listener.session[:session_var].should == "Second"
|
|
170
|
-
end
|
|
171
|
-
|
|
172
|
-
should "return value of channel variable" do
|
|
173
|
-
command_reply :body => "+OK"
|
|
174
|
-
|
|
175
|
-
@listener.should update_session 1234
|
|
176
|
-
api_response :body => {
|
|
177
|
-
"Event-Name" => "CHANNEL_DATA",
|
|
178
|
-
"variable_app_var" => "Second"
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
@listener.should send_application "send", "Second"
|
|
182
|
-
end
|
|
183
|
-
end
|
|
184
|
-
|
|
185
|
-
class OutboundListenerWithNonNestedApps < Librevox::Listener::Outbound
|
|
186
|
-
attr_reader :queue
|
|
187
|
-
def session_initiated
|
|
188
|
-
sample_app "foo" do
|
|
189
|
-
reader_app do |data|
|
|
190
|
-
application "send", "the end: #{data}"
|
|
191
|
-
end
|
|
192
|
-
end
|
|
193
|
-
end
|
|
194
|
-
end
|
|
195
|
-
|
|
196
|
-
describe "Outbound listener with non-nested apps" do
|
|
197
|
-
extend Librevox::Test::Matchers
|
|
198
|
-
|
|
199
|
-
before do
|
|
200
|
-
@listener = OutboundListenerWithNonNestedApps.new(nil)
|
|
201
|
-
|
|
202
|
-
command_reply "Session-Var" => "First",
|
|
203
|
-
"Unique-ID" => "1234"
|
|
204
|
-
event_and_linger_replies
|
|
205
|
-
3.times {@listener.outgoing_data.shift}
|
|
206
|
-
end
|
|
207
|
-
|
|
208
|
-
should "wait for response before calling next app" do
|
|
209
|
-
@listener.should send_application "foo"
|
|
210
|
-
command_reply :body => "+OK"
|
|
211
|
-
@listener.should update_session
|
|
212
|
-
channel_data "Unique-ID" => "1234"
|
|
213
|
-
|
|
214
|
-
@listener.should send_application "reader_app"
|
|
215
|
-
command_reply :body => "+OK"
|
|
216
|
-
|
|
217
|
-
@listener.should update_session
|
|
218
|
-
api_response :body => {
|
|
219
|
-
"Event-Name" => "CHANNEL_DATA",
|
|
220
|
-
"variable_app_var" => "Second"
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
@listener.should send_application "send", "the end: Second"
|
|
224
|
-
end
|
|
225
|
-
end
|
|
226
|
-
|
|
227
|
-
module Librevox::Commands
|
|
228
|
-
def sample_cmd cmd, *args, &block
|
|
229
|
-
command cmd, *args, &block
|
|
230
|
-
end
|
|
231
|
-
end
|
|
232
|
-
|
|
233
|
-
class OutboundListenerWithAppsAndApi < Librevox::Listener::Outbound
|
|
234
|
-
def session_initiated
|
|
235
|
-
sample_app "foo" do
|
|
236
|
-
api.sample_cmd "bar" do
|
|
237
|
-
sample_app "baz"
|
|
238
|
-
end
|
|
239
|
-
end
|
|
240
|
-
end
|
|
241
|
-
end
|
|
242
|
-
|
|
243
|
-
describe "Outbound listener with both apps and api calls" do
|
|
244
|
-
extend Librevox::Test::Matchers
|
|
245
|
-
|
|
246
|
-
before do
|
|
247
|
-
@listener = OutboundListenerWithAppsAndApi.new(nil)
|
|
248
|
-
|
|
249
|
-
command_reply "Session-Var" => "First",
|
|
250
|
-
"Unique-ID" => "1234"
|
|
251
|
-
event_and_linger_replies
|
|
252
|
-
3.times {@listener.outgoing_data.shift}
|
|
253
|
-
end
|
|
254
|
-
|
|
255
|
-
should "wait for response before calling next app/cmd" do
|
|
256
|
-
@listener.should send_application "foo"
|
|
257
|
-
command_reply :body => "+OK"
|
|
258
|
-
@listener.should update_session
|
|
259
|
-
channel_data
|
|
260
|
-
|
|
261
|
-
@listener.should send_command "api bar"
|
|
262
|
-
api_response :body => "+OK"
|
|
263
|
-
|
|
264
|
-
@listener.should send_application "baz"
|
|
265
|
-
end
|
|
266
|
-
end
|
|
267
|
-
|
|
268
|
-
class OutboundListenerWithUpdateSessionCallback < Librevox::Listener::Outbound
|
|
269
|
-
def session_initiated
|
|
270
|
-
update_session do
|
|
271
|
-
application "send", "yay, #{session[:session_var]}"
|
|
272
|
-
end
|
|
273
|
-
end
|
|
274
|
-
end
|
|
275
|
-
|
|
276
|
-
describe "Outbound listener with update session callback" do
|
|
277
|
-
extend Librevox::Test::Matchers
|
|
278
|
-
|
|
279
|
-
before do
|
|
280
|
-
@listener = OutboundListenerWithUpdateSessionCallback.new(nil)
|
|
281
|
-
command_reply "Session-Var" => "First",
|
|
282
|
-
"Unique-ID" => "1234"
|
|
283
|
-
event_and_linger_replies
|
|
284
|
-
3.times {@listener.outgoing_data.shift}
|
|
285
|
-
|
|
286
|
-
@listener.should update_session
|
|
287
|
-
api_response :body => {
|
|
288
|
-
"Event-Name" => "CHANNEL_DATA",
|
|
289
|
-
"Session-Var" => "Second"
|
|
290
|
-
}
|
|
291
|
-
end
|
|
292
|
-
|
|
293
|
-
should "execute callback" do
|
|
294
|
-
@listener.outgoing_data.shift.should =~ /yay,/
|
|
295
|
-
end
|
|
296
|
-
|
|
297
|
-
should "update session before calling callback" do
|
|
298
|
-
@listener.should send_application "send", "yay, Second"
|
|
299
|
-
end
|
|
300
|
-
end
|
data/spec/librevox/listener.rb
DELETED
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
require './spec/helper'
|
|
2
|
-
require 'librevox/listener/base'
|
|
3
|
-
|
|
4
|
-
include Librevox::Test::ListenerHelpers
|
|
5
|
-
|
|
6
|
-
class Librevox::Listener::Base
|
|
7
|
-
attr_accessor :outgoing_data
|
|
8
|
-
|
|
9
|
-
def initialize(*args)
|
|
10
|
-
@outgoing_data = []
|
|
11
|
-
super *args
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def send_data(data)
|
|
15
|
-
@outgoing_data << data
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def read_data
|
|
19
|
-
@outgoing_data.pop
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
# These tests are a bit fragile, as they depend on event hooks being
|
|
24
|
-
# executed before on_event.
|
|
25
|
-
shared "events" do
|
|
26
|
-
before do
|
|
27
|
-
@class = @listener.class
|
|
28
|
-
|
|
29
|
-
@class.event(:some_event) {send_data "something"}
|
|
30
|
-
@class.event(:other_event) {send_data "something else"}
|
|
31
|
-
@class.event(:hook_with_arg) {|e| send_data "got event arg: #{e.object_id}"}
|
|
32
|
-
|
|
33
|
-
def @listener.on_event(e)
|
|
34
|
-
send_data "from on_event: #{e.object_id}"
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
# Establish session
|
|
38
|
-
@listener.receive_data("Content-Length: 0\nTest: Testing\n\n")
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
should "add event hook" do
|
|
42
|
-
@class.hooks.size.should == 3
|
|
43
|
-
@class.hooks.each do |event, hooks|
|
|
44
|
-
hooks.size.should == 1
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
should "execute callback for event" do
|
|
49
|
-
event "OTHER_EVENT"
|
|
50
|
-
@listener.read_data.should == "something else"
|
|
51
|
-
|
|
52
|
-
event "SOME_EVENT"
|
|
53
|
-
@listener.read_data.should == "something"
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
should "pass response duplicate as arg to hook block" do
|
|
57
|
-
event "HOOK_WITH_ARG"
|
|
58
|
-
|
|
59
|
-
reply = @listener.read_data
|
|
60
|
-
reply.should =~ /^got event arg: /
|
|
61
|
-
reply.should.not =~ /^got event arg: #{@listener.response.object_id}$/
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
should "expose response as event" do
|
|
65
|
-
event "OTHER_EVENT"
|
|
66
|
-
|
|
67
|
-
@listener.event.class.should == Librevox::Response
|
|
68
|
-
@listener.event.content[:event_name].should == "OTHER_EVENT"
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
should "call on_event" do
|
|
72
|
-
event "THIRD_EVENT"
|
|
73
|
-
|
|
74
|
-
@listener.read_data.should =~ /^from on_event/
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
should "call on_event with response duplicate as argument" do
|
|
78
|
-
event "THIRD_EVENT"
|
|
79
|
-
|
|
80
|
-
@listener.read_data.should.not =~ /^from on_event: #{@listener.response.object_id}$/
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
should "call event hooks and on_event on CHANNEL_DATA" do
|
|
84
|
-
@listener.outgoing_data.clear
|
|
85
|
-
|
|
86
|
-
def @listener.on_event e
|
|
87
|
-
send_data "on_event: CHANNEL_DATA test"
|
|
88
|
-
end
|
|
89
|
-
@class.event(:channel_data) {send_data "event hook: CHANNEL_DATA test"}
|
|
90
|
-
|
|
91
|
-
event "CHANNEL_DATA"
|
|
92
|
-
|
|
93
|
-
@listener.outgoing_data.should.include "on_event: CHANNEL_DATA test"
|
|
94
|
-
@listener.outgoing_data.should.include "event hook: CHANNEL_DATA test"
|
|
95
|
-
end
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
module Librevox::Commands
|
|
99
|
-
def sample_cmd cmd, args="", &block
|
|
100
|
-
command cmd, args, &block
|
|
101
|
-
end
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
shared "api commands" do
|
|
105
|
-
before do
|
|
106
|
-
@class = @listener.class
|
|
107
|
-
|
|
108
|
-
# Establish session
|
|
109
|
-
command_reply "Test" => "Testing"
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
describe "multiple api commands" do
|
|
113
|
-
extend Librevox::Test::Matchers
|
|
114
|
-
|
|
115
|
-
before do
|
|
116
|
-
@listener.outgoing_data.clear
|
|
117
|
-
|
|
118
|
-
def @listener.on_event(e) end # Don't send anything, kthx.
|
|
119
|
-
|
|
120
|
-
@class.event(:api_test) {
|
|
121
|
-
api.sample_cmd "foo" do
|
|
122
|
-
api.sample_cmd "foo", "bar baz" do |r|
|
|
123
|
-
command "response #{r.content}"
|
|
124
|
-
end
|
|
125
|
-
end
|
|
126
|
-
}
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
should "only send one command at a time, and return response for commands" do
|
|
130
|
-
command_reply :body => {"Event-Name" => "API_TEST"}
|
|
131
|
-
@listener.should send_command "api foo"
|
|
132
|
-
@listener.should send_nothing
|
|
133
|
-
|
|
134
|
-
api_response "Reply-Text" => "+OK"
|
|
135
|
-
@listener.should send_command "api foo bar baz"
|
|
136
|
-
@listener.should send_nothing
|
|
137
|
-
|
|
138
|
-
api_response :body => "+YAY"
|
|
139
|
-
@listener.should send_command "response +YAY"
|
|
140
|
-
end
|
|
141
|
-
end
|
|
142
|
-
end
|