punchblock 1.9.4 → 2.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (142) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +1 -2
  4. data/CHANGELOG.md +17 -0
  5. data/Gemfile +1 -0
  6. data/Guardfile +4 -0
  7. data/README.markdown +6 -0
  8. data/Rakefile +16 -0
  9. data/benchmarks/ami_event_name_comparison.rb +14 -0
  10. data/benchmarks/channel.rb +27 -0
  11. data/lib/punchblock/client.rb +2 -6
  12. data/lib/punchblock/command/accept.rb +3 -24
  13. data/lib/punchblock/command/answer.rb +3 -24
  14. data/lib/punchblock/command/dial.rb +24 -76
  15. data/lib/punchblock/command/hangup.rb +3 -19
  16. data/lib/punchblock/command/join.rb +21 -70
  17. data/lib/punchblock/command/mute.rb +3 -3
  18. data/lib/punchblock/command/redirect.rb +6 -39
  19. data/lib/punchblock/command/reject.rb +14 -54
  20. data/lib/punchblock/command/unjoin.rb +8 -40
  21. data/lib/punchblock/command/unmute.rb +3 -3
  22. data/lib/punchblock/command_node.rb +0 -17
  23. data/lib/punchblock/component/asterisk/agi/command.rb +20 -127
  24. data/lib/punchblock/component/asterisk/ami/action.rb +30 -117
  25. data/lib/punchblock/component/component_node.rb +1 -1
  26. data/lib/punchblock/component/input.rb +89 -268
  27. data/lib/punchblock/component/output.rb +106 -154
  28. data/lib/punchblock/component/prompt.rb +51 -0
  29. data/lib/punchblock/component/record.rb +41 -130
  30. data/lib/punchblock/component.rb +1 -0
  31. data/lib/punchblock/connection/asterisk.rb +31 -4
  32. data/lib/punchblock/connection/xmpp.rb +6 -14
  33. data/lib/punchblock/core_ext/blather/stanza.rb +1 -1
  34. data/lib/punchblock/event/active_speaker.rb +2 -10
  35. data/lib/punchblock/event/answered.rb +3 -3
  36. data/lib/punchblock/event/asterisk/ami/event.rb +15 -47
  37. data/lib/punchblock/event/complete.rb +26 -48
  38. data/lib/punchblock/event/dtmf.rb +3 -13
  39. data/lib/punchblock/event/end.rb +10 -11
  40. data/lib/punchblock/event/joined.rb +5 -25
  41. data/lib/punchblock/event/offer.rb +4 -25
  42. data/lib/punchblock/event/ringing.rb +3 -3
  43. data/lib/punchblock/event/unjoined.rb +5 -25
  44. data/lib/punchblock/event.rb +0 -10
  45. data/lib/punchblock/has_headers.rb +20 -26
  46. data/lib/punchblock/rayo_node.rb +46 -23
  47. data/lib/punchblock/ref.rb +39 -18
  48. data/lib/punchblock/translator/asterisk/agi_app.rb +15 -0
  49. data/lib/punchblock/translator/asterisk/agi_command.rb +3 -1
  50. data/lib/punchblock/translator/asterisk/ami_error_converter.rb +20 -0
  51. data/lib/punchblock/translator/asterisk/call.rb +60 -39
  52. data/lib/punchblock/translator/asterisk/channel.rb +41 -0
  53. data/lib/punchblock/translator/asterisk/component/asterisk/agi_command.rb +4 -1
  54. data/lib/punchblock/translator/asterisk/component/asterisk/ami_action.rb +4 -4
  55. data/lib/punchblock/translator/asterisk/component/composed_prompt.rb +62 -0
  56. data/lib/punchblock/translator/asterisk/component/input.rb +1 -0
  57. data/lib/punchblock/translator/asterisk/component/mrcp_native_prompt.rb +56 -0
  58. data/lib/punchblock/translator/asterisk/component/mrcp_prompt.rb +53 -0
  59. data/lib/punchblock/translator/asterisk/component/mrcp_recog_prompt.rb +99 -0
  60. data/lib/punchblock/translator/asterisk/component/output.rb +30 -22
  61. data/lib/punchblock/translator/asterisk/component/record.rb +8 -6
  62. data/lib/punchblock/translator/asterisk/component.rb +6 -5
  63. data/lib/punchblock/translator/asterisk/unimrcp_app.rb +26 -0
  64. data/lib/punchblock/translator/asterisk.rb +24 -28
  65. data/lib/punchblock/translator/dtmf_recognizer.rb +39 -20
  66. data/lib/punchblock/translator/freeswitch/call.rb +15 -14
  67. data/lib/punchblock/translator/freeswitch/component/abstract_output.rb +5 -4
  68. data/lib/punchblock/translator/freeswitch/component/flite_output.rb +1 -1
  69. data/lib/punchblock/translator/freeswitch/component/input.rb +5 -0
  70. data/lib/punchblock/translator/freeswitch/component/output.rb +2 -2
  71. data/lib/punchblock/translator/freeswitch/component/record.rb +19 -13
  72. data/lib/punchblock/translator/freeswitch/component/tts_output.rb +2 -2
  73. data/lib/punchblock/translator/freeswitch/component.rb +2 -5
  74. data/lib/punchblock/translator/freeswitch.rb +2 -2
  75. data/lib/punchblock/translator/input_component.rb +33 -13
  76. data/lib/punchblock/uri_list.rb +21 -0
  77. data/lib/punchblock/version.rb +1 -1
  78. data/lib/punchblock.rb +4 -3
  79. data/punchblock.gemspec +7 -3
  80. data/spec/punchblock/client/component_registry_spec.rb +1 -1
  81. data/spec/punchblock/client_spec.rb +10 -26
  82. data/spec/punchblock/command/accept_spec.rb +41 -7
  83. data/spec/punchblock/command/answer_spec.rb +51 -7
  84. data/spec/punchblock/command/dial_spec.rb +56 -14
  85. data/spec/punchblock/command/hangup_spec.rb +41 -7
  86. data/spec/punchblock/command/join_spec.rb +53 -11
  87. data/spec/punchblock/command/mute_spec.rb +19 -4
  88. data/spec/punchblock/command/redirect_spec.rb +40 -10
  89. data/spec/punchblock/command/reject_spec.rb +43 -11
  90. data/spec/punchblock/command/unjoin_spec.rb +40 -9
  91. data/spec/punchblock/command/unmute_spec.rb +19 -4
  92. data/spec/punchblock/command_node_spec.rb +0 -4
  93. data/spec/punchblock/component/asterisk/agi/command_spec.rb +16 -39
  94. data/spec/punchblock/component/asterisk/ami/action_spec.rb +50 -53
  95. data/spec/punchblock/component/component_node_spec.rb +3 -5
  96. data/spec/punchblock/component/input_spec.rb +194 -61
  97. data/spec/punchblock/component/output_spec.rb +194 -62
  98. data/spec/punchblock/component/prompt_spec.rb +132 -0
  99. data/spec/punchblock/component/record_spec.rb +70 -32
  100. data/spec/punchblock/connection/asterisk_spec.rb +17 -3
  101. data/spec/punchblock/connection/freeswitch_spec.rb +4 -4
  102. data/spec/punchblock/connection/xmpp_spec.rb +20 -38
  103. data/spec/punchblock/event/answered_spec.rb +12 -10
  104. data/spec/punchblock/event/asterisk/ami/event_spec.rb +27 -22
  105. data/spec/punchblock/event/complete_spec.rb +15 -19
  106. data/spec/punchblock/event/dtmf_spec.rb +5 -6
  107. data/spec/punchblock/event/end_spec.rb +20 -10
  108. data/spec/punchblock/event/joined_spec.rb +8 -7
  109. data/spec/punchblock/event/offer_spec.rb +41 -12
  110. data/spec/punchblock/event/ringing_spec.rb +12 -10
  111. data/spec/punchblock/event/started_speaking_spec.rb +5 -6
  112. data/spec/punchblock/event/stopped_speaking_spec.rb +5 -6
  113. data/spec/punchblock/event/unjoined_spec.rb +7 -7
  114. data/spec/punchblock/ref_spec.rb +86 -9
  115. data/spec/punchblock/translator/asterisk/call_spec.rb +317 -154
  116. data/spec/punchblock/translator/asterisk/component/asterisk/agi_command_spec.rb +28 -5
  117. data/spec/punchblock/translator/asterisk/component/asterisk/ami_action_spec.rb +15 -13
  118. data/spec/punchblock/translator/asterisk/component/composed_prompt_spec.rb +237 -0
  119. data/spec/punchblock/translator/asterisk/component/input_spec.rb +171 -14
  120. data/spec/punchblock/translator/asterisk/component/mrcp_native_prompt_spec.rb +652 -0
  121. data/spec/punchblock/translator/asterisk/component/mrcp_prompt_spec.rb +646 -0
  122. data/spec/punchblock/translator/asterisk/component/output_spec.rb +127 -77
  123. data/spec/punchblock/translator/asterisk/component/record_spec.rb +17 -8
  124. data/spec/punchblock/translator/asterisk/component/stop_by_redirect_spec.rb +2 -2
  125. data/spec/punchblock/translator/asterisk/component_spec.rb +3 -7
  126. data/spec/punchblock/translator/asterisk_spec.rb +20 -24
  127. data/spec/punchblock/translator/freeswitch/call_spec.rb +103 -99
  128. data/spec/punchblock/translator/freeswitch/component/flite_output_spec.rb +17 -8
  129. data/spec/punchblock/translator/freeswitch/component/input_spec.rb +26 -14
  130. data/spec/punchblock/translator/freeswitch/component/output_spec.rb +30 -52
  131. data/spec/punchblock/translator/freeswitch/component/record_spec.rb +23 -19
  132. data/spec/punchblock/translator/freeswitch/component/tts_output_spec.rb +18 -8
  133. data/spec/punchblock/translator/freeswitch/component_spec.rb +4 -8
  134. data/spec/punchblock/translator/freeswitch_spec.rb +11 -14
  135. data/spec/punchblock/uri_list_spec.rb +49 -0
  136. data/spec/punchblock_spec.rb +11 -1
  137. data/spec/spec_helper.rb +7 -11
  138. data/spec/support/mock_connection_with_event_handler.rb +1 -1
  139. metadata +104 -24
  140. data/lib/punchblock/header.rb +0 -9
  141. data/lib/punchblock/key_value_pair_node.rb +0 -51
  142. data/spec/punchblock/header_spec.rb +0 -11
@@ -11,7 +11,7 @@ module Punchblock
11
11
 
12
12
  let(:id) { Punchblock.new_uuid }
13
13
  let(:translator) { Punchblock::Translator::Freeswitch.new connection }
14
- let(:mock_stream) { mock('RubyFS::Stream') }
14
+ let(:mock_stream) { double('RubyFS::Stream') }
15
15
  let(:mock_call) { Punchblock::Translator::Freeswitch::Call.new id, translator, nil, mock_stream }
16
16
 
17
17
  let :original_command do
@@ -48,7 +48,7 @@ module Punchblock
48
48
  subject.execute
49
49
  end
50
50
 
51
- it "sends a success complete event when the recording ends" do
51
+ it "sends a maxduration complete event when the recording ends" do
52
52
  full_filename = "file://#{filename}"
53
53
  subject.execute
54
54
  record_stop_event = RubyFS::Event.new nil, {
@@ -56,7 +56,7 @@ module Punchblock
56
56
  :record_file_path => filename
57
57
  }
58
58
  mock_call.handle_es_event record_stop_event
59
- reason.should be_a Punchblock::Component::Record::Complete::Success
59
+ reason.should be_a Punchblock::Component::Record::Complete::MaxDuration
60
60
  recording.uri.should be == full_filename
61
61
  original_command.should be_complete
62
62
  end
@@ -94,8 +94,9 @@ module Punchblock
94
94
  describe 'initial_timeout' do
95
95
  context "set to nil" do
96
96
  let(:command_options) { { :initial_timeout => nil } }
97
- it "should execute normally" do
98
- mock_call.should_receive(:uuid_foo).once.with(:record, /.wav$/)
97
+ it "should setvar RECORD_INITIAL_TIMEOUT_MS with a 0 value" do
98
+ mock_call.should_receive(:uuid_foo).once.with(:setvar, "RECORD_INITIAL_TIMEOUT_MS 0").ordered
99
+ mock_call.should_receive(:uuid_foo).once.with(:record, /.wav$/).ordered
99
100
  subject.execute
100
101
  original_command.response(0.1).should be_a Ref
101
102
  end
@@ -103,8 +104,9 @@ module Punchblock
103
104
 
104
105
  context "set to -1" do
105
106
  let(:command_options) { { :initial_timeout => -1 } }
106
- it "should execute normally" do
107
- mock_call.should_receive(:uuid_foo).once.with(:record, /.wav$/)
107
+ it "should setvar RECORD_INITIAL_TIMEOUT_MS with a 0 value" do
108
+ mock_call.should_receive(:uuid_foo).once.with(:setvar, "RECORD_INITIAL_TIMEOUT_MS 0").ordered
109
+ mock_call.should_receive(:uuid_foo).once.with(:record, /.wav$/).ordered
108
110
  subject.execute
109
111
  original_command.response(0.1).should be_a Ref
110
112
  end
@@ -112,11 +114,11 @@ module Punchblock
112
114
 
113
115
  context "set to a positive number" do
114
116
  let(:command_options) { { :initial_timeout => 10 } }
115
- it "should return an error and not execute any actions" do
116
- mock_call.should_receive(:uuid_foo).never
117
+ it "should setvar RECORD_INITIAL_TIMEOUT_MS with a value in ms" do
118
+ mock_call.should_receive(:uuid_foo).once.with(:setvar, "RECORD_INITIAL_TIMEOUT_MS 10").ordered
119
+ mock_call.should_receive(:uuid_foo).once.with(:record, /.wav$/).ordered
117
120
  subject.execute
118
- error = ProtocolError.new.setup 'option error', 'An initial-timeout value is unsupported.'
119
- original_command.response(0.1).should be == error
121
+ original_command.response(0.1).should be_a Ref
120
122
  end
121
123
  end
122
124
  end
@@ -124,8 +126,9 @@ module Punchblock
124
126
  describe 'final_timeout' do
125
127
  context "set to nil" do
126
128
  let(:command_options) { { :final_timeout => nil } }
127
- it "should execute normally" do
128
- mock_call.should_receive(:uuid_foo).once.with(:record, /.wav$/)
129
+ it "should setvar RECORD_FINAL_TIMEOUT_MS with a 0 value" do
130
+ mock_call.should_receive(:uuid_foo).once.with(:setvar, "RECORD_FINAL_TIMEOUT_MS 0").ordered
131
+ mock_call.should_receive(:uuid_foo).once.with(:record, /.wav$/).ordered
129
132
  subject.execute
130
133
  original_command.response(0.1).should be_a Ref
131
134
  end
@@ -133,8 +136,9 @@ module Punchblock
133
136
 
134
137
  context "set to -1" do
135
138
  let(:command_options) { { :final_timeout => -1 } }
136
- it "should execute normally" do
137
- mock_call.should_receive(:uuid_foo).once.with(:record, /.wav$/)
139
+ it "should setvar RECORD_FINAL_TIMEOUT_MS with a 0 value" do
140
+ mock_call.should_receive(:uuid_foo).once.with(:setvar, "RECORD_FINAL_TIMEOUT_MS 0").ordered
141
+ mock_call.should_receive(:uuid_foo).once.with(:record, /.wav$/).ordered
138
142
  subject.execute
139
143
  original_command.response(0.1).should be_a Ref
140
144
  end
@@ -142,11 +146,11 @@ module Punchblock
142
146
 
143
147
  context "set to a positive number" do
144
148
  let(:command_options) { { :final_timeout => 10 } }
145
- it "should return an error and not execute any actions" do
146
- mock_call.should_receive(:uuid_foo).never
149
+ it "should setvar RECORD_FINAL_TIMEOUT_MS with a value in ms" do
150
+ mock_call.should_receive(:uuid_foo).once.with(:setvar, "RECORD_FINAL_TIMEOUT_MS 10").ordered
151
+ mock_call.should_receive(:uuid_foo).once.with(:record, /.wav$/).ordered
147
152
  subject.execute
148
- error = ProtocolError.new.setup 'option error', 'A final-timeout value is unsupported.'
149
- original_command.response(0.1).should be == error
153
+ original_command.response(0.1).should be_a Ref
150
154
  end
151
155
  end
152
156
  end
@@ -25,7 +25,7 @@ module Punchblock
25
25
  end
26
26
 
27
27
  let :command_options do
28
- { :ssml => ssml_doc }
28
+ { :render_document => {:value => ssml_doc} }
29
29
  end
30
30
 
31
31
  def execute
@@ -49,16 +49,17 @@ module Punchblock
49
49
  let(:command_opts) { {} }
50
50
 
51
51
  let :command_options do
52
- { :ssml => ssml_doc }.merge(command_opts)
52
+ { :render_document => {:value => ssml_doc} }.merge(command_opts)
53
53
  end
54
54
 
55
55
  let :original_command do
56
56
  Punchblock::Component::Output.new command_options
57
57
  end
58
58
 
59
- describe 'ssml' do
59
+ describe 'document' do
60
60
  context 'unset' do
61
- let(:command_opts) { { :ssml => nil } }
61
+ let(:ssml_doc) { nil }
62
+
62
63
  it "should return an error and not execute any actions" do
63
64
  execute
64
65
  error = ProtocolError.new.setup 'option error', 'An SSML document is required.'
@@ -76,7 +77,16 @@ module Punchblock
76
77
  expect_playback
77
78
  execute
78
79
  subject.handle_es_event RubyFS::Event.new(nil, :event_name => "CHANNEL_EXECUTE_COMPLETE")
79
- original_command.complete_event(0.1).reason.should be_a Punchblock::Component::Output::Complete::Success
80
+ original_command.complete_event(0.1).reason.should be_a Punchblock::Component::Output::Complete::Finish
81
+ end
82
+ end
83
+
84
+ context 'with multiple documents' do
85
+ let(:command_opts) { { :render_documents => [{:value => ssml_doc}, {:value => ssml_doc}] } }
86
+ it "should return an error and not execute any actions" do
87
+ subject.execute
88
+ error = ProtocolError.new.setup 'option error', 'Only a single document is supported.'
89
+ original_command.response(0.1).should be == error
80
90
  end
81
91
  end
82
92
  end
@@ -221,11 +231,11 @@ module Punchblock
221
231
  end
222
232
  end
223
233
 
224
- context "set to :speech" do
225
- let(:command_opts) { { :interrupt_on => :speech } }
234
+ context "set to :voice" do
235
+ let(:command_opts) { { :interrupt_on => :voice } }
226
236
  it "should return an error and not execute any actions" do
227
237
  execute
228
- error = ProtocolError.new.setup 'option error', 'An interrupt-on value of speech is unsupported.'
238
+ error = ProtocolError.new.setup 'option error', 'An interrupt-on value of voice is unsupported.'
229
239
  original_command.response(0.1).should be == error
230
240
  end
231
241
  end
@@ -26,7 +26,7 @@ module Punchblock
26
26
  RubyFS::Event.new nil, :event_name => 'CHANNEL_EXECUTE'
27
27
  end
28
28
 
29
- let(:response) { mock 'Response' }
29
+ let(:response) { double 'Response' }
30
30
 
31
31
  it 'should execute the handler' do
32
32
  response.should_receive(:call).once.with es_event
@@ -46,10 +46,8 @@ module Punchblock
46
46
  end
47
47
 
48
48
  let :expected_event do
49
- Punchblock::Event::Complete.new.tap do |e|
50
- e.target_call_id = call.id
51
- e.component_id = subject.id
52
- end
49
+ Punchblock::Event::Complete.new target_call_id: call.id,
50
+ component_id: subject.id
53
51
  end
54
52
 
55
53
  it "should send the event to the connection" do
@@ -63,9 +61,7 @@ module Punchblock
63
61
 
64
62
  let(:reason) { Punchblock::Event::Complete::Stop.new }
65
63
  let :expected_event do
66
- Punchblock::Event::Complete.new.tap do |c|
67
- c.reason = Punchblock::Event::Complete::Stop.new
68
- end
64
+ Punchblock::Event::Complete.new reason: reason
69
65
  end
70
66
 
71
67
  it "should send a complete event with the specified reason" do
@@ -5,12 +5,12 @@ require 'spec_helper'
5
5
  module Punchblock
6
6
  module Translator
7
7
  describe Freeswitch do
8
- let(:connection) { mock 'Connection::Freeswitch' }
8
+ let(:connection) { double 'Connection::Freeswitch' }
9
9
  let(:media_engine) { :flite }
10
10
  let(:default_voice) { :hal }
11
11
 
12
12
  let(:translator) { described_class.new connection, media_engine, default_voice }
13
- let(:stream) { mock 'RubyFS::Stream' }
13
+ let(:stream) { double 'RubyFS::Stream' }
14
14
 
15
15
  before { connection.should_receive(:stream).at_most(:once).and_return stream }
16
16
 
@@ -88,14 +88,14 @@ module Punchblock
88
88
 
89
89
  it 'should make the call inaccessible by ID' do
90
90
  subject.call_with_id(call_id).should be call
91
- subject.deregister_call call
91
+ subject.deregister_call call_id
92
92
  subject.call_with_id(call_id).should be_nil
93
93
  end
94
94
  end
95
95
 
96
96
  describe '#register_component' do
97
97
  let(:component_id) { 'abc123' }
98
- let(:component) { mock 'Foo', :id => component_id }
98
+ let(:component) { double 'Foo', :id => component_id }
99
99
 
100
100
  it 'should make the component accessible by ID' do
101
101
  subject.register_component component
@@ -105,7 +105,7 @@ module Punchblock
105
105
 
106
106
  describe '#execute_call_command' do
107
107
  let(:call_id) { 'abc123' }
108
- let(:command) { Command::Answer.new.tap { |c| c.target_call_id = call_id } }
108
+ let(:command) { Command::Answer.new target_call_id: call_id }
109
109
 
110
110
  context "with a known call ID" do
111
111
  let(:call) { described_class::Call.new 'SIP/foo', subject }
@@ -123,16 +123,13 @@ module Punchblock
123
123
  end
124
124
 
125
125
  let :end_error_event do
126
- Punchblock::Event::End.new.tap do |e|
127
- e.target_call_id = call_id
128
- e.reason = :error
129
- end
126
+ Punchblock::Event::End.new reason: :error, target_call_id: call_id
130
127
  end
131
128
 
132
129
  context "for an outgoing call which began executing but crashed" do
133
130
  let(:dial_command) { Command::Dial.new :to => 'SIP/1234', :from => 'abc123' }
134
131
 
135
- let(:call_id) { dial_command.response.id }
132
+ let(:call_id) { dial_command.response.call_id }
136
133
 
137
134
  before do
138
135
  stream.as_null_object
@@ -205,7 +202,7 @@ module Punchblock
205
202
  let(:component_node) { Component::Output.new }
206
203
  let(:component) { Translator::Freeswitch::Component::Output.new(component_node, call) }
207
204
 
208
- let(:command) { Component::Stop.new.tap { |c| c.component_id = component.id } }
205
+ let(:command) { Component::Stop.new component_id: component.id }
209
206
 
210
207
  before do
211
208
  command.request!
@@ -256,7 +253,7 @@ module Punchblock
256
253
  end
257
254
 
258
255
  it 'should instruct the call to send a dial' do
259
- mock_call = stub('Freeswitch::Call').as_null_object
256
+ mock_call = double('Freeswitch::Call').as_null_object
260
257
  Freeswitch::Call.should_receive(:new_link).once.and_return mock_call
261
258
  mock_call.async.should_receive(:dial).once.with command
262
259
  subject.execute_global_command command
@@ -277,7 +274,7 @@ module Punchblock
277
274
 
278
275
  describe '#handle_pb_event' do
279
276
  it 'should forward the event to the connection' do
280
- event = mock 'Punchblock::Event'
277
+ event = double 'Punchblock::Event'
281
278
  subject.connection.should_receive(:handle_event).once.with event
282
279
  subject.handle_pb_event event
283
280
  end
@@ -530,7 +527,7 @@ module Punchblock
530
527
 
531
528
  describe 'with a CHANNEL_PARK event' do
532
529
  it 'should instruct the call to send an offer' do
533
- mock_call = stub('Freeswitch::Call').as_null_object
530
+ mock_call = double('Freeswitch::Call').as_null_object
534
531
  Freeswitch::Call.should_receive(:new).once.and_return mock_call
535
532
  subject.wrapped_object.should_receive(:link)
536
533
  mock_call.async.should_receive(:send_offer).once
@@ -0,0 +1,49 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Punchblock::URIList do
6
+ its(:size) { should == 0 }
7
+
8
+ context "created with a set of entries" do
9
+ subject { described_class.new 'http://example.com/hello.mp3', 'http://example.com/goodbye.mp3' }
10
+
11
+ its(:size) { should == 2 }
12
+ its(:to_ary) { should == ['http://example.com/hello.mp3', 'http://example.com/goodbye.mp3'] }
13
+
14
+ its(:to_s) { should == "http://example.com/hello.mp3\nhttp://example.com/goodbye.mp3" }
15
+ end
16
+
17
+ context "created with an array of entries" do
18
+ subject { described_class.new ['http://example.com/hello.mp3', 'http://example.com/goodbye.mp3'] }
19
+
20
+ its(:size) { should == 2 }
21
+ its(:to_ary) { should == ['http://example.com/hello.mp3', 'http://example.com/goodbye.mp3'] }
22
+ its(:to_s) { should == "http://example.com/hello.mp3\nhttp://example.com/goodbye.mp3" }
23
+ end
24
+
25
+ context "imported from a string" do
26
+ let(:string) do
27
+ <<-STRING
28
+ http://example.com/hello.mp3
29
+ http://example.com/goodbye.mp3
30
+ STRING
31
+ end
32
+
33
+ subject { described_class.import string }
34
+
35
+ its(:size) { should == 2 }
36
+ its(:to_ary) { should == ['http://example.com/hello.mp3', 'http://example.com/goodbye.mp3'] }
37
+ its(:to_s) { should == "http://example.com/hello.mp3\nhttp://example.com/goodbye.mp3" }
38
+ end
39
+
40
+ describe "comparisons" do
41
+ context "when the elements are the same" do
42
+ described_class.new('foo', 'bar').should == described_class.new('foo', 'bar')
43
+ end
44
+
45
+ context "when the elements are different" do
46
+ described_class.new('foo', 'baz').should_not == described_class.new('bar', 'baz')
47
+ end
48
+ end
49
+ end
@@ -2,7 +2,17 @@ require 'spec_helper'
2
2
 
3
3
  describe Punchblock do
4
4
  describe '#client_with_connection' do
5
- let(:mock_connection) { stub('Connection').as_null_object }
5
+ let(:mock_connection) { double('Connection').as_null_object }
6
+
7
+ context 'with :xmpp' do
8
+ it 'sets up an XMPP connection, passing options, and a client with the connection attached' do
9
+ options = {:username => 'foo', :password => 'bar'}
10
+ Punchblock::Connection::XMPP.should_receive(:new).once.with(options).and_return mock_connection
11
+ client = Punchblock.client_with_connection :xmpp, options
12
+ client.should be_a Punchblock::Client
13
+ client.connection.should be mock_connection
14
+ end
15
+ end
6
16
 
7
17
  context 'with :XMPP' do
8
18
  it 'sets up an XMPP connection, passing options, and a client with the connection attached' do
data/spec/spec_helper.rb CHANGED
@@ -3,6 +3,9 @@
3
3
  require 'punchblock'
4
4
  require 'countdownlatch'
5
5
  require 'logger'
6
+ require 'celluloid'
7
+ require 'coveralls'
8
+ Coveralls.wear!
6
9
 
7
10
  Dir[File.dirname(__FILE__) + "/support/**/*.rb"].each {|f| require f}
8
11
 
@@ -12,6 +15,10 @@ RSpec.configure do |config|
12
15
  config.filter_run :focus => true
13
16
  config.run_all_when_everything_filtered = true
14
17
 
18
+ config.mock_with :rspec do |mocks|
19
+ mocks.add_stub_and_should_receive_to Celluloid::AbstractProxy
20
+ end
21
+
15
22
  config.before :suite do |variable|
16
23
  Punchblock.logger = Logger.new(STDOUT)
17
24
  Punchblock.logger.define_singleton_method :trace, Punchblock.logger.method(:debug)
@@ -42,20 +49,9 @@ shared_examples_for 'event' do
42
49
  end
43
50
 
44
51
  shared_examples_for 'command_headers' do
45
- it 'takes a hash of keys and values for headers' do
46
- headers = { :x_skill => 'agent', :x_customer_id => '8877' }
47
-
48
- control = [ Punchblock::Header.new(:x_skill, 'agent'), Punchblock::Header.new(:x_customer_id, '8877')]
49
-
50
- di = subject.class.new :headers => headers
51
- di.headers.should have(2).items
52
- di.headers.each { |i| control.include?(i).should be_true }
53
- end
54
52
  end
55
53
 
56
54
  shared_examples_for 'event_headers' do
57
- its(:headers) { should be == [Punchblock::Header.new('X-skill', 'agent'), Punchblock::Header.new('X-customer-id', '8877')]}
58
- its(:headers_hash) { should be == {:x_skill => 'agent', :x_customer_id => '8877'} }
59
55
  end
60
56
 
61
57
  shared_examples_for 'key_value_pairs' do
@@ -3,7 +3,7 @@
3
3
  module HasMockCallbackConnection
4
4
  def self.included(test_case)
5
5
  test_case.let(:connection) do
6
- mock('Connection').tap do |mc|
6
+ double('Connection').tap do |mc|
7
7
  mc.stub :handle_event do |event|
8
8
  original_command.add_event event
9
9
  end