punchblock 1.0.0 → 1.1.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/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # [develop](https://github.com/adhearsion/punchblock)
2
2
 
3
+ # [v1.1.0](https://github.com/adhearsion/punchblock/compare/v1.0.0...v1.1.0) - [2012-04-26](https://rubygems.org/gems/punchblock/versions/1.1.0)
4
+ * Feature: Implement Reject on Asterisk
5
+ * Bugfix: No longer generate warnings
6
+ * Bugfix: Set 'to' attribute on an offer from Asterisk to something useful if the dnid is 'unknown'
7
+ * Bugfix: Include caller ID name in 'from' attribute on an offer from Asterisk
8
+ * Bugfix: Removed media engine switching on Asterisk Input component - fixes broken input when using app_swift or unimrcp for output
9
+ * Update: Better dependency version fixing
10
+
3
11
  # [v1.0.0](https://github.com/adhearsion/punchblock/compare/v0.12.0...v1.0.0) - [2012-04-11](https://rubygems.org/gems/punchblock/versions/1.0.0)
4
12
  * Stable release :D
5
13
  * Bugfix: Any issue in compiling an output document into executable elements on Asterisk should return an unrenderable doc error
data/Rakefile CHANGED
@@ -1,4 +1,3 @@
1
- require 'rubygems'
2
1
  require 'bundler/gem_tasks'
3
2
  require 'bundler/setup'
4
3
 
@@ -193,6 +193,20 @@ module Punchblock
193
193
  when Command::Unjoin
194
194
  other_call = translator.call_with_id command.call_id
195
195
  redirect_back other_call
196
+ when Command::Reject
197
+ rejection = case command.reason
198
+ when :busy
199
+ 'EXEC Busy'
200
+ when :decline
201
+ 'EXEC Busy'
202
+ when :error
203
+ 'EXEC Congestion'
204
+ else
205
+ 'EXEC Congestion'
206
+ end
207
+ send_agi_action rejection do |response|
208
+ command.response = true
209
+ end
196
210
  when Punchblock::Component::Asterisk::AGI::Command
197
211
  execute_component Component::Asterisk::AGICommand, command
198
212
  when Punchblock::Component::Output
@@ -265,8 +279,8 @@ module Punchblock
265
279
  end
266
280
 
267
281
  def offer_event
268
- Event::Offer.new :to => agi_env[:agi_dnid],
269
- :from => [agi_env[:agi_type].downcase, agi_env[:agi_callerid]].join(':'),
282
+ Event::Offer.new :to => agi_env.values_at(:agi_dnid, :agi_extension).detect { |e| e && e != 'unknown' },
283
+ :from => "#{agi_env[:agi_calleridname]} <#{[agi_env[:agi_type].downcase, agi_env[:agi_callerid]].join(':')}>",
270
284
  :headers => sip_headers
271
285
  end
272
286
 
@@ -9,8 +9,7 @@ module Punchblock
9
9
  attr_reader :grammar, :buffer
10
10
 
11
11
  def setup
12
- @media_engine = call.translator.media_engine
13
- @buffer = ""
12
+ @buffer = ""
14
13
  end
15
14
 
16
15
  def execute
@@ -25,22 +24,19 @@ module Punchblock
25
24
 
26
25
  send_ref
27
26
 
28
- case @media_engine
29
- when :asterisk, nil
30
- @grammar = @component_node.grammar.value.clone
31
- grammar.inline!
32
- grammar.tokenize!
33
- grammar.normalize_whitespace
27
+ @grammar = @component_node.grammar.value.clone
28
+ grammar.inline!
29
+ grammar.tokenize!
30
+ grammar.normalize_whitespace
34
31
 
35
- begin_initial_timer initial_timeout/1000 unless initial_timeout == -1
32
+ begin_initial_timer initial_timeout/1000 unless initial_timeout == -1
36
33
 
37
- component = current_actor
34
+ component = current_actor
38
35
 
39
- @active = true
36
+ @active = true
40
37
 
41
- call.register_handler :ami, :name => 'DTMF' do |event|
42
- component.process_dtmf! event['Digit'] if event['End'] == 'Yes'
43
- end
38
+ call.register_handler :ami, :name => 'DTMF' do |event|
39
+ component.process_dtmf! event['Digit'] if event['End'] == 'Yes'
44
40
  end
45
41
  rescue OptionError => e
46
42
  with_error 'option error', e.message
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module Punchblock
4
- VERSION = "1.0.0"
4
+ VERSION = "1.1.0"
5
5
  end
data/punchblock.gemspec CHANGED
@@ -22,23 +22,24 @@ Gem::Specification.new do |s|
22
22
 
23
23
  s.required_rubygems_version = Gem::Requirement.new(">= 1.3.7") if s.respond_to? :required_rubygems_version=
24
24
 
25
- s.add_runtime_dependency %q<niceogiri>, [">= 0.0.4"]
26
- s.add_runtime_dependency %q<blather>, [">= 0.5.12"]
27
- s.add_runtime_dependency %q<activesupport>, [">= 2.1.0"]
28
- s.add_runtime_dependency %q<state_machine>, [">= 1.0.1"]
29
- s.add_runtime_dependency %q<future-resource>, [">= 0.0.2"]
30
- s.add_runtime_dependency %q<has-guarded-handlers>, [">= 0.1.0"]
31
- s.add_runtime_dependency %q<celluloid>, [">= 0.9.0"]
32
- s.add_runtime_dependency %q<ruby_ami>, [">= 0.1.3"]
33
- s.add_runtime_dependency %q<ruby_speech>, [">= 0.5.1"]
25
+ s.add_runtime_dependency %q<niceogiri>, ["~> 1.0"]
26
+ s.add_runtime_dependency %q<blather>, [">= 0.7.0"]
27
+ s.add_runtime_dependency %q<activesupport>, ["~> 3.0"]
28
+ s.add_runtime_dependency %q<state_machine>, ["~> 1.0"]
29
+ s.add_runtime_dependency %q<future-resource>, ["~> 1.0"]
30
+ s.add_runtime_dependency %q<has-guarded-handlers>, ["~> 1.0"]
31
+ s.add_runtime_dependency %q<celluloid>, [">= 0.10.0"]
32
+ s.add_runtime_dependency %q<ruby_ami>, ["~> 1.0"]
33
+ s.add_runtime_dependency %q<ruby_speech>, ["~> 1.0"]
34
34
 
35
35
  s.add_development_dependency %q<bundler>, [">= 1.0.0"]
36
36
  s.add_development_dependency %q<rspec>, ["~> 2.7.0"]
37
37
  s.add_development_dependency %q<ci_reporter>, [">= 1.6.3"]
38
- s.add_development_dependency %q<yard>, ["~> 0.6.0"]
38
+ s.add_development_dependency %q<yard>, [">= 0.6.0"]
39
39
  s.add_development_dependency %q<rake>, [">= 0"]
40
40
  s.add_development_dependency %q<mocha>, [">= 0"]
41
41
  s.add_development_dependency %q<i18n>, [">= 0"]
42
42
  s.add_development_dependency %q<countdownlatch>, [">= 0"]
43
43
  s.add_development_dependency %q<guard-rspec>
44
+ s.add_development_dependency %q<ruby_gntp>
44
45
  end
@@ -28,10 +28,10 @@ module Punchblock
28
28
  context "with other values" do
29
29
  it "returns a new object with the appropriate values" do
30
30
  e = ProtocolError.exception 'FooBar'
31
- e.name.should == nil
32
- e.text.should == nil
33
- e.call_id.should == nil
34
- e.component_id.should == nil
31
+ e.name.should be == nil
32
+ e.text.should be == nil
33
+ e.call_id.should be == nil
34
+ e.component_id.should be == nil
35
35
  end
36
36
  end
37
37
  end
@@ -52,10 +52,10 @@ module Punchblock
52
52
  context "with other values" do
53
53
  it "returns a new object with the appropriate values" do
54
54
  e = subject.exception("Boo")
55
- e.name.should == name
56
- e.text.should == text
57
- e.call_id.should == call_id
58
- e.component_id.should == component_id
55
+ e.name.should be == name
56
+ e.text.should be == text
57
+ e.call_id.should be == call_id
58
+ e.component_id.should be == component_id
59
59
  end
60
60
  end
61
61
  end
@@ -22,7 +22,7 @@ module Punchblock
22
22
  :agi_callingani2 => '0',
23
23
  :agi_callington => '0',
24
24
  :agi_callingtns => '0',
25
- :agi_dnid => '1000',
25
+ :agi_dnid => 'unknown',
26
26
  :agi_rdnis => 'unknown',
27
27
  :agi_context => 'default',
28
28
  :agi_extension => '1000',
@@ -47,7 +47,7 @@ module Punchblock
47
47
  :x_agi_callingani2 => '0',
48
48
  :x_agi_callington => '0',
49
49
  :x_agi_callingtns => '0',
50
- :x_agi_dnid => '1000',
50
+ :x_agi_dnid => 'unknown',
51
51
  :x_agi_rdnis => 'unknown',
52
52
  :x_agi_context => 'default',
53
53
  :x_agi_extension => '1000',
@@ -86,7 +86,7 @@ module Punchblock
86
86
  it 'sends an offer to the translator' do
87
87
  expected_offer = Punchblock::Event::Offer.new :target_call_id => subject.id,
88
88
  :to => '1000',
89
- :from => 'sip:5678',
89
+ :from => 'Jane Smith <sip:5678>',
90
90
  :headers => sip_headers
91
91
  translator.expects(:handle_pb_event!).with expected_offer
92
92
  subject.send_offer
@@ -651,6 +651,43 @@ module Punchblock
651
651
  end
652
652
  end
653
653
 
654
+ context 'with a reject command' do
655
+ let(:command) { Command::Reject.new }
656
+
657
+ it "with a :busy reason should send an EXEC Busy AGI command and set the command's response" do
658
+ command.reason = :busy
659
+ component = subject.execute_command command
660
+ component.internal.should be_true
661
+ agi_command = subject.wrapped_object.instance_variable_get(:'@current_agi_command')
662
+ agi_command.name.should be == "EXEC Busy"
663
+ agi_command.execute!
664
+ agi_command.add_event expected_agi_complete_event
665
+ command.response(0.5).should be true
666
+ end
667
+
668
+ it "with a :decline reason should send an EXEC Busy AGI command and set the command's response" do
669
+ command.reason = :decline
670
+ component = subject.execute_command command
671
+ component.internal.should be_true
672
+ agi_command = subject.wrapped_object.instance_variable_get(:'@current_agi_command')
673
+ agi_command.name.should be == "EXEC Busy"
674
+ agi_command.execute!
675
+ agi_command.add_event expected_agi_complete_event
676
+ command.response(0.5).should be true
677
+ end
678
+
679
+ it "with an :error reason should send an EXEC Congestion AGI command and set the command's response" do
680
+ command.reason = :error
681
+ component = subject.execute_command command
682
+ component.internal.should be_true
683
+ agi_command = subject.wrapped_object.instance_variable_get(:'@current_agi_command')
684
+ agi_command.name.should be == "EXEC Congestion"
685
+ agi_command.execute!
686
+ agi_command.add_event expected_agi_complete_event
687
+ command.response(0.5).should be true
688
+ end
689
+ end
690
+
654
691
  context 'with an answer command' do
655
692
  let(:command) { Command::Answer.new }
656
693
 
@@ -49,240 +49,231 @@ module Punchblock
49
49
 
50
50
  before { call.stubs :answer_if_not_answered }
51
51
 
52
- context 'with a media engine of :unimrcp' do
53
- pending
54
- let(:media_engine) { :unimrcp }
52
+ let(:original_command_opts) { {} }
53
+
54
+ let :original_command_options do
55
+ { :mode => :dtmf, :grammar => { :value => grammar } }.merge(original_command_opts)
56
+ end
57
+
58
+ def ami_event_for_dtmf(digit, position)
59
+ RubyAMI::Event.new('DTMF').tap do |e|
60
+ e['Digit'] = digit.to_s
61
+ e['Start'] = position == :start ? 'Yes' : 'No'
62
+ e['End'] = position == :end ? 'Yes' : 'No'
63
+ end
55
64
  end
56
65
 
57
- context 'with a media engine of :asterisk' do
58
- let(:media_engine) { :asterisk }
66
+ def send_ami_events_for_dtmf(digit)
67
+ call.process_ami_event ami_event_for_dtmf(digit, :start)
68
+ call.process_ami_event ami_event_for_dtmf(digit, :end)
69
+ end
59
70
 
60
- let(:original_command_opts) { {} }
71
+ let(:reason) { original_command.complete_event(5).reason }
61
72
 
62
- let :original_command_options do
63
- { :mode => :dtmf, :grammar => { :value => grammar } }.merge(original_command_opts)
73
+ describe "receiving DTMF events" do
74
+ before do
75
+ subject.execute
76
+ expected_event
64
77
  end
65
78
 
66
- def ami_event_for_dtmf(digit, position)
67
- RubyAMI::Event.new('DTMF').tap do |e|
68
- e['Digit'] = digit.to_s
69
- e['Start'] = position == :start ? 'Yes' : 'No'
70
- e['End'] = position == :end ? 'Yes' : 'No'
79
+ context "when a match is found" do
80
+ before do
81
+ send_ami_events_for_dtmf 1
82
+ send_ami_events_for_dtmf 2
83
+ end
84
+
85
+ let :expected_event do
86
+ Punchblock::Component::Input::Complete::Success.new :mode => :dtmf,
87
+ :confidence => 1,
88
+ :utterance => '12',
89
+ :interpretation => 'dtmf-1 dtmf-2',
90
+ :component_id => subject.id,
91
+ :target_call_id => call.id
71
92
  end
72
- end
73
93
 
74
- def send_ami_events_for_dtmf(digit)
75
- call.process_ami_event ami_event_for_dtmf(digit, :start)
76
- call.process_ami_event ami_event_for_dtmf(digit, :end)
94
+ it "should send a success complete event with the relevant data" do
95
+ reason.should be == expected_event
96
+ end
77
97
  end
78
98
 
79
- let(:reason) { original_command.complete_event(5).reason }
80
-
81
- describe "receiving DTMF events" do
99
+ context "when the match is invalid" do
82
100
  before do
83
- subject.execute
84
- expected_event
101
+ send_ami_events_for_dtmf 1
102
+ send_ami_events_for_dtmf '#'
85
103
  end
86
104
 
87
- context "when a match is found" do
88
- before do
89
- send_ami_events_for_dtmf 1
90
- send_ami_events_for_dtmf 2
91
- end
92
-
93
- let :expected_event do
94
- Punchblock::Component::Input::Complete::Success.new :mode => :dtmf,
95
- :confidence => 1,
96
- :utterance => '12',
97
- :interpretation => 'dtmf-1 dtmf-2',
98
- :component_id => subject.id,
99
- :target_call_id => call.id
100
- end
101
-
102
- it "should send a success complete event with the relevant data" do
103
- reason.should be == expected_event
104
- end
105
+ let :expected_event do
106
+ Punchblock::Component::Input::Complete::NoMatch.new :component_id => subject.id,
107
+ :target_call_id => call.id
105
108
  end
106
109
 
107
- context "when the match is invalid" do
108
- before do
109
- send_ami_events_for_dtmf 1
110
- send_ami_events_for_dtmf '#'
111
- end
112
-
113
- let :expected_event do
114
- Punchblock::Component::Input::Complete::NoMatch.new :component_id => subject.id,
115
- :target_call_id => call.id
116
- end
117
-
118
- it "should send a nomatch complete event" do
119
- reason.should be == expected_event
120
- end
110
+ it "should send a nomatch complete event" do
111
+ reason.should be == expected_event
121
112
  end
122
113
  end
114
+ end
123
115
 
124
- describe 'grammar' do
125
- context 'unset' do
126
- let(:original_command_opts) { { :grammar => nil } }
127
- it "should return an error and not execute any actions" do
128
- subject.execute
129
- error = ProtocolError.new.setup 'option error', 'A grammar document is required.'
130
- original_command.response(0.1).should be == error
131
- end
116
+ describe 'grammar' do
117
+ context 'unset' do
118
+ let(:original_command_opts) { { :grammar => nil } }
119
+ it "should return an error and not execute any actions" do
120
+ subject.execute
121
+ error = ProtocolError.new.setup 'option error', 'A grammar document is required.'
122
+ original_command.response(0.1).should be == error
132
123
  end
133
124
  end
125
+ end
134
126
 
135
- describe 'mode' do
136
- context 'unset' do
137
- let(:original_command_opts) { { :mode => nil } }
138
- it "should return an error and not execute any actions" do
139
- subject.execute
140
- error = ProtocolError.new.setup 'option error', 'A mode value other than DTMF is unsupported on Asterisk.'
141
- original_command.response(0.1).should be == error
142
- end
127
+ describe 'mode' do
128
+ context 'unset' do
129
+ let(:original_command_opts) { { :mode => nil } }
130
+ it "should return an error and not execute any actions" do
131
+ subject.execute
132
+ error = ProtocolError.new.setup 'option error', 'A mode value other than DTMF is unsupported on Asterisk.'
133
+ original_command.response(0.1).should be == error
143
134
  end
135
+ end
144
136
 
145
- context 'any' do
146
- let(:original_command_opts) { { :mode => :any } }
147
- it "should return an error and not execute any actions" do
148
- subject.execute
149
- error = ProtocolError.new.setup 'option error', 'A mode value other than DTMF is unsupported on Asterisk.'
150
- original_command.response(0.1).should be == error
151
- end
137
+ context 'any' do
138
+ let(:original_command_opts) { { :mode => :any } }
139
+ it "should return an error and not execute any actions" do
140
+ subject.execute
141
+ error = ProtocolError.new.setup 'option error', 'A mode value other than DTMF is unsupported on Asterisk.'
142
+ original_command.response(0.1).should be == error
152
143
  end
144
+ end
153
145
 
154
- context 'speech' do
155
- let(:original_command_opts) { { :mode => :speech } }
156
- it "should return an error and not execute any actions" do
157
- subject.execute
158
- error = ProtocolError.new.setup 'option error', 'A mode value other than DTMF is unsupported on Asterisk.'
159
- original_command.response(0.1).should be == error
160
- end
146
+ context 'speech' do
147
+ let(:original_command_opts) { { :mode => :speech } }
148
+ it "should return an error and not execute any actions" do
149
+ subject.execute
150
+ error = ProtocolError.new.setup 'option error', 'A mode value other than DTMF is unsupported on Asterisk.'
151
+ original_command.response(0.1).should be == error
161
152
  end
162
153
  end
154
+ end
163
155
 
164
- describe 'terminator' do
165
- pending
166
- end
156
+ describe 'terminator' do
157
+ pending
158
+ end
167
159
 
168
- describe 'recognizer' do
169
- pending
170
- end
160
+ describe 'recognizer' do
161
+ pending
162
+ end
171
163
 
172
- describe 'initial-timeout' do
173
- context 'a positive number' do
174
- let(:original_command_opts) { { :initial_timeout => 1000 } }
175
-
176
- it "should not cause a NoInput if first input is received in time" do
177
- subject.execute
178
- send_ami_events_for_dtmf 1
179
- sleep 1.5
180
- send_ami_events_for_dtmf 2
181
- reason.should be_a Punchblock::Component::Input::Complete::Success
182
- end
183
-
184
- it "should cause a NoInput complete event to be sent after the timeout" do
185
- subject.execute
186
- sleep 1.5
187
- send_ami_events_for_dtmf 1
188
- send_ami_events_for_dtmf 2
189
- reason.should be_a Punchblock::Component::Input::Complete::NoInput
190
- end
191
- end
164
+ describe 'initial-timeout' do
165
+ context 'a positive number' do
166
+ let(:original_command_opts) { { :initial_timeout => 1000 } }
192
167
 
193
- context '-1' do
194
- let(:original_command_opts) { { :initial_timeout => -1 } }
168
+ it "should not cause a NoInput if first input is received in time" do
169
+ subject.execute
170
+ send_ami_events_for_dtmf 1
171
+ sleep 1.5
172
+ send_ami_events_for_dtmf 2
173
+ reason.should be_a Punchblock::Component::Input::Complete::Success
174
+ end
195
175
 
196
- it "should not start a timer" do
197
- subject.wrapped_object.expects(:begin_initial_timer).never
198
- subject.execute
199
- end
176
+ it "should cause a NoInput complete event to be sent after the timeout" do
177
+ subject.execute
178
+ sleep 1.5
179
+ send_ami_events_for_dtmf 1
180
+ send_ami_events_for_dtmf 2
181
+ reason.should be_a Punchblock::Component::Input::Complete::NoInput
200
182
  end
183
+ end
201
184
 
202
- context 'unset' do
203
- let(:original_command_opts) { { :initial_timeout => nil } }
185
+ context '-1' do
186
+ let(:original_command_opts) { { :initial_timeout => -1 } }
204
187
 
205
- it "should not start a timer" do
206
- subject.wrapped_object.expects(:begin_initial_timer).never
207
- subject.execute
208
- end
188
+ it "should not start a timer" do
189
+ subject.wrapped_object.expects(:begin_initial_timer).never
190
+ subject.execute
209
191
  end
192
+ end
210
193
 
211
- context 'a negative number other than -1' do
212
- let(:original_command_opts) { { :initial_timeout => -1000 } }
194
+ context 'unset' do
195
+ let(:original_command_opts) { { :initial_timeout => nil } }
213
196
 
214
- it "should return an error and not execute any actions" do
215
- subject.execute
216
- error = ProtocolError.new.setup 'option error', 'An initial timeout value that is negative (and not -1) is invalid.'
217
- original_command.response(0.1).should be == error
218
- end
197
+ it "should not start a timer" do
198
+ subject.wrapped_object.expects(:begin_initial_timer).never
199
+ subject.execute
219
200
  end
220
201
  end
221
202
 
222
- describe 'inter-digit-timeout' do
223
- context 'a positive number' do
224
- let(:original_command_opts) { { :inter_digit_timeout => 1000 } }
225
-
226
- it "should not prevent a Match if input is received in time" do
227
- subject.execute
228
- sleep 1.5
229
- send_ami_events_for_dtmf 1
230
- sleep 0.5
231
- send_ami_events_for_dtmf 2
232
- reason.should be_a Punchblock::Component::Input::Complete::Success
233
- end
234
-
235
- it "should cause a NoMatch complete event to be sent after the timeout" do
236
- subject.execute
237
- sleep 1.5
238
- send_ami_events_for_dtmf 1
239
- sleep 1.5
240
- send_ami_events_for_dtmf 2
241
- reason.should be_a Punchblock::Component::Input::Complete::NoMatch
242
- end
203
+ context 'a negative number other than -1' do
204
+ let(:original_command_opts) { { :initial_timeout => -1000 } }
205
+
206
+ it "should return an error and not execute any actions" do
207
+ subject.execute
208
+ error = ProtocolError.new.setup 'option error', 'An initial timeout value that is negative (and not -1) is invalid.'
209
+ original_command.response(0.1).should be == error
243
210
  end
211
+ end
212
+ end
244
213
 
245
- context '-1' do
246
- let(:original_command_opts) { { :inter_digit_timeout => -1 } }
214
+ describe 'inter-digit-timeout' do
215
+ context 'a positive number' do
216
+ let(:original_command_opts) { { :inter_digit_timeout => 1000 } }
247
217
 
248
- it "should not start a timer" do
249
- subject.wrapped_object.expects(:begin_inter_digit_timer).never
250
- subject.execute
251
- end
218
+ it "should not prevent a Match if input is received in time" do
219
+ subject.execute
220
+ sleep 1.5
221
+ send_ami_events_for_dtmf 1
222
+ sleep 0.5
223
+ send_ami_events_for_dtmf 2
224
+ reason.should be_a Punchblock::Component::Input::Complete::Success
252
225
  end
253
226
 
254
- context 'unset' do
255
- let(:original_command_opts) { { :inter_digit_timeout => nil } }
256
-
257
- it "should not start a timer" do
258
- subject.wrapped_object.expects(:begin_inter_digit_timer).never
259
- subject.execute
260
- end
227
+ it "should cause a NoMatch complete event to be sent after the timeout" do
228
+ subject.execute
229
+ sleep 1.5
230
+ send_ami_events_for_dtmf 1
231
+ sleep 1.5
232
+ send_ami_events_for_dtmf 2
233
+ reason.should be_a Punchblock::Component::Input::Complete::NoMatch
261
234
  end
235
+ end
262
236
 
263
- context 'a negative number other than -1' do
264
- let(:original_command_opts) { { :inter_digit_timeout => -1000 } }
237
+ context '-1' do
238
+ let(:original_command_opts) { { :inter_digit_timeout => -1 } }
265
239
 
266
- it "should return an error and not execute any actions" do
267
- subject.execute
268
- error = ProtocolError.new.setup 'option error', 'An inter-digit timeout value that is negative (and not -1) is invalid.'
269
- original_command.response(0.1).should be == error
270
- end
240
+ it "should not start a timer" do
241
+ subject.wrapped_object.expects(:begin_inter_digit_timer).never
242
+ subject.execute
271
243
  end
272
244
  end
273
245
 
274
- describe 'sensitivity' do
275
- pending
276
- end
246
+ context 'unset' do
247
+ let(:original_command_opts) { { :inter_digit_timeout => nil } }
277
248
 
278
- describe 'min-confidence' do
279
- pending
249
+ it "should not start a timer" do
250
+ subject.wrapped_object.expects(:begin_inter_digit_timer).never
251
+ subject.execute
252
+ end
280
253
  end
281
254
 
282
- describe 'max-silence' do
283
- pending
255
+ context 'a negative number other than -1' do
256
+ let(:original_command_opts) { { :inter_digit_timeout => -1000 } }
257
+
258
+ it "should return an error and not execute any actions" do
259
+ subject.execute
260
+ error = ProtocolError.new.setup 'option error', 'An inter-digit timeout value that is negative (and not -1) is invalid.'
261
+ original_command.response(0.1).should be == error
262
+ end
284
263
  end
285
264
  end
265
+
266
+ describe 'sensitivity' do
267
+ pending
268
+ end
269
+
270
+ describe 'min-confidence' do
271
+ pending
272
+ end
273
+
274
+ describe 'max-silence' do
275
+ pending
276
+ end
286
277
  end
287
278
 
288
279
  describe "#execute_command" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: punchblock
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -11,110 +11,155 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2012-04-11 00:00:00.000000000 Z
14
+ date: 2012-04-26 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: niceogiri
18
- requirement: &2151853680 !ruby/object:Gem::Requirement
18
+ requirement: !ruby/object:Gem::Requirement
19
19
  none: false
20
20
  requirements:
21
- - - ! '>='
21
+ - - ~>
22
22
  - !ruby/object:Gem::Version
23
- version: 0.0.4
23
+ version: '1.0'
24
24
  type: :runtime
25
25
  prerelease: false
26
- version_requirements: *2151853680
26
+ version_requirements: !ruby/object:Gem::Requirement
27
+ none: false
28
+ requirements:
29
+ - - ~>
30
+ - !ruby/object:Gem::Version
31
+ version: '1.0'
27
32
  - !ruby/object:Gem::Dependency
28
33
  name: blather
29
- requirement: &2151852020 !ruby/object:Gem::Requirement
34
+ requirement: !ruby/object:Gem::Requirement
30
35
  none: false
31
36
  requirements:
32
37
  - - ! '>='
33
38
  - !ruby/object:Gem::Version
34
- version: 0.5.12
39
+ version: 0.7.0
35
40
  type: :runtime
36
41
  prerelease: false
37
- version_requirements: *2151852020
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ none: false
44
+ requirements:
45
+ - - ! '>='
46
+ - !ruby/object:Gem::Version
47
+ version: 0.7.0
38
48
  - !ruby/object:Gem::Dependency
39
49
  name: activesupport
40
- requirement: &2151864820 !ruby/object:Gem::Requirement
50
+ requirement: !ruby/object:Gem::Requirement
41
51
  none: false
42
52
  requirements:
43
- - - ! '>='
53
+ - - ~>
44
54
  - !ruby/object:Gem::Version
45
- version: 2.1.0
55
+ version: '3.0'
46
56
  type: :runtime
47
57
  prerelease: false
48
- version_requirements: *2151864820
58
+ version_requirements: !ruby/object:Gem::Requirement
59
+ none: false
60
+ requirements:
61
+ - - ~>
62
+ - !ruby/object:Gem::Version
63
+ version: '3.0'
49
64
  - !ruby/object:Gem::Dependency
50
65
  name: state_machine
51
- requirement: &2151861640 !ruby/object:Gem::Requirement
66
+ requirement: !ruby/object:Gem::Requirement
52
67
  none: false
53
68
  requirements:
54
- - - ! '>='
69
+ - - ~>
55
70
  - !ruby/object:Gem::Version
56
- version: 1.0.1
71
+ version: '1.0'
57
72
  type: :runtime
58
73
  prerelease: false
59
- version_requirements: *2151861640
74
+ version_requirements: !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ~>
78
+ - !ruby/object:Gem::Version
79
+ version: '1.0'
60
80
  - !ruby/object:Gem::Dependency
61
81
  name: future-resource
62
- requirement: &2151860660 !ruby/object:Gem::Requirement
82
+ requirement: !ruby/object:Gem::Requirement
63
83
  none: false
64
84
  requirements:
65
- - - ! '>='
85
+ - - ~>
66
86
  - !ruby/object:Gem::Version
67
- version: 0.0.2
87
+ version: '1.0'
68
88
  type: :runtime
69
89
  prerelease: false
70
- version_requirements: *2151860660
90
+ version_requirements: !ruby/object:Gem::Requirement
91
+ none: false
92
+ requirements:
93
+ - - ~>
94
+ - !ruby/object:Gem::Version
95
+ version: '1.0'
71
96
  - !ruby/object:Gem::Dependency
72
97
  name: has-guarded-handlers
73
- requirement: &2151875260 !ruby/object:Gem::Requirement
98
+ requirement: !ruby/object:Gem::Requirement
74
99
  none: false
75
100
  requirements:
76
- - - ! '>='
101
+ - - ~>
77
102
  - !ruby/object:Gem::Version
78
- version: 0.1.0
103
+ version: '1.0'
79
104
  type: :runtime
80
105
  prerelease: false
81
- version_requirements: *2151875260
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ none: false
108
+ requirements:
109
+ - - ~>
110
+ - !ruby/object:Gem::Version
111
+ version: '1.0'
82
112
  - !ruby/object:Gem::Dependency
83
113
  name: celluloid
84
- requirement: &2151879400 !ruby/object:Gem::Requirement
114
+ requirement: !ruby/object:Gem::Requirement
85
115
  none: false
86
116
  requirements:
87
117
  - - ! '>='
88
118
  - !ruby/object:Gem::Version
89
- version: 0.9.0
119
+ version: 0.10.0
90
120
  type: :runtime
91
121
  prerelease: false
92
- version_requirements: *2151879400
122
+ version_requirements: !ruby/object:Gem::Requirement
123
+ none: false
124
+ requirements:
125
+ - - ! '>='
126
+ - !ruby/object:Gem::Version
127
+ version: 0.10.0
93
128
  - !ruby/object:Gem::Dependency
94
129
  name: ruby_ami
95
- requirement: &2152058520 !ruby/object:Gem::Requirement
130
+ requirement: !ruby/object:Gem::Requirement
96
131
  none: false
97
132
  requirements:
98
- - - ! '>='
133
+ - - ~>
99
134
  - !ruby/object:Gem::Version
100
- version: 0.1.3
135
+ version: '1.0'
101
136
  type: :runtime
102
137
  prerelease: false
103
- version_requirements: *2152058520
138
+ version_requirements: !ruby/object:Gem::Requirement
139
+ none: false
140
+ requirements:
141
+ - - ~>
142
+ - !ruby/object:Gem::Version
143
+ version: '1.0'
104
144
  - !ruby/object:Gem::Dependency
105
145
  name: ruby_speech
106
- requirement: &2152083720 !ruby/object:Gem::Requirement
146
+ requirement: !ruby/object:Gem::Requirement
107
147
  none: false
108
148
  requirements:
109
- - - ! '>='
149
+ - - ~>
110
150
  - !ruby/object:Gem::Version
111
- version: 0.5.1
151
+ version: '1.0'
112
152
  type: :runtime
113
153
  prerelease: false
114
- version_requirements: *2152083720
154
+ version_requirements: !ruby/object:Gem::Requirement
155
+ none: false
156
+ requirements:
157
+ - - ~>
158
+ - !ruby/object:Gem::Version
159
+ version: '1.0'
115
160
  - !ruby/object:Gem::Dependency
116
161
  name: bundler
117
- requirement: &2152086540 !ruby/object:Gem::Requirement
162
+ requirement: !ruby/object:Gem::Requirement
118
163
  none: false
119
164
  requirements:
120
165
  - - ! '>='
@@ -122,10 +167,15 @@ dependencies:
122
167
  version: 1.0.0
123
168
  type: :development
124
169
  prerelease: false
125
- version_requirements: *2152086540
170
+ version_requirements: !ruby/object:Gem::Requirement
171
+ none: false
172
+ requirements:
173
+ - - ! '>='
174
+ - !ruby/object:Gem::Version
175
+ version: 1.0.0
126
176
  - !ruby/object:Gem::Dependency
127
177
  name: rspec
128
- requirement: &2152093960 !ruby/object:Gem::Requirement
178
+ requirement: !ruby/object:Gem::Requirement
129
179
  none: false
130
180
  requirements:
131
181
  - - ~>
@@ -133,10 +183,15 @@ dependencies:
133
183
  version: 2.7.0
134
184
  type: :development
135
185
  prerelease: false
136
- version_requirements: *2152093960
186
+ version_requirements: !ruby/object:Gem::Requirement
187
+ none: false
188
+ requirements:
189
+ - - ~>
190
+ - !ruby/object:Gem::Version
191
+ version: 2.7.0
137
192
  - !ruby/object:Gem::Dependency
138
193
  name: ci_reporter
139
- requirement: &2152106160 !ruby/object:Gem::Requirement
194
+ requirement: !ruby/object:Gem::Requirement
140
195
  none: false
141
196
  requirements:
142
197
  - - ! '>='
@@ -144,21 +199,31 @@ dependencies:
144
199
  version: 1.6.3
145
200
  type: :development
146
201
  prerelease: false
147
- version_requirements: *2152106160
202
+ version_requirements: !ruby/object:Gem::Requirement
203
+ none: false
204
+ requirements:
205
+ - - ! '>='
206
+ - !ruby/object:Gem::Version
207
+ version: 1.6.3
148
208
  - !ruby/object:Gem::Dependency
149
209
  name: yard
150
- requirement: &2152101260 !ruby/object:Gem::Requirement
210
+ requirement: !ruby/object:Gem::Requirement
151
211
  none: false
152
212
  requirements:
153
- - - ~>
213
+ - - ! '>='
154
214
  - !ruby/object:Gem::Version
155
215
  version: 0.6.0
156
216
  type: :development
157
217
  prerelease: false
158
- version_requirements: *2152101260
218
+ version_requirements: !ruby/object:Gem::Requirement
219
+ none: false
220
+ requirements:
221
+ - - ! '>='
222
+ - !ruby/object:Gem::Version
223
+ version: 0.6.0
159
224
  - !ruby/object:Gem::Dependency
160
225
  name: rake
161
- requirement: &2151949040 !ruby/object:Gem::Requirement
226
+ requirement: !ruby/object:Gem::Requirement
162
227
  none: false
163
228
  requirements:
164
229
  - - ! '>='
@@ -166,10 +231,15 @@ dependencies:
166
231
  version: '0'
167
232
  type: :development
168
233
  prerelease: false
169
- version_requirements: *2151949040
234
+ version_requirements: !ruby/object:Gem::Requirement
235
+ none: false
236
+ requirements:
237
+ - - ! '>='
238
+ - !ruby/object:Gem::Version
239
+ version: '0'
170
240
  - !ruby/object:Gem::Dependency
171
241
  name: mocha
172
- requirement: &2151961660 !ruby/object:Gem::Requirement
242
+ requirement: !ruby/object:Gem::Requirement
173
243
  none: false
174
244
  requirements:
175
245
  - - ! '>='
@@ -177,10 +247,15 @@ dependencies:
177
247
  version: '0'
178
248
  type: :development
179
249
  prerelease: false
180
- version_requirements: *2151961660
250
+ version_requirements: !ruby/object:Gem::Requirement
251
+ none: false
252
+ requirements:
253
+ - - ! '>='
254
+ - !ruby/object:Gem::Version
255
+ version: '0'
181
256
  - !ruby/object:Gem::Dependency
182
257
  name: i18n
183
- requirement: &2151959840 !ruby/object:Gem::Requirement
258
+ requirement: !ruby/object:Gem::Requirement
184
259
  none: false
185
260
  requirements:
186
261
  - - ! '>='
@@ -188,10 +263,15 @@ dependencies:
188
263
  version: '0'
189
264
  type: :development
190
265
  prerelease: false
191
- version_requirements: *2151959840
266
+ version_requirements: !ruby/object:Gem::Requirement
267
+ none: false
268
+ requirements:
269
+ - - ! '>='
270
+ - !ruby/object:Gem::Version
271
+ version: '0'
192
272
  - !ruby/object:Gem::Dependency
193
273
  name: countdownlatch
194
- requirement: &2151958260 !ruby/object:Gem::Requirement
274
+ requirement: !ruby/object:Gem::Requirement
195
275
  none: false
196
276
  requirements:
197
277
  - - ! '>='
@@ -199,10 +279,15 @@ dependencies:
199
279
  version: '0'
200
280
  type: :development
201
281
  prerelease: false
202
- version_requirements: *2151958260
282
+ version_requirements: !ruby/object:Gem::Requirement
283
+ none: false
284
+ requirements:
285
+ - - ! '>='
286
+ - !ruby/object:Gem::Version
287
+ version: '0'
203
288
  - !ruby/object:Gem::Dependency
204
289
  name: guard-rspec
205
- requirement: &2152122840 !ruby/object:Gem::Requirement
290
+ requirement: !ruby/object:Gem::Requirement
206
291
  none: false
207
292
  requirements:
208
293
  - - ! '>='
@@ -210,7 +295,28 @@ dependencies:
210
295
  version: '0'
211
296
  type: :development
212
297
  prerelease: false
213
- version_requirements: *2152122840
298
+ version_requirements: !ruby/object:Gem::Requirement
299
+ none: false
300
+ requirements:
301
+ - - ! '>='
302
+ - !ruby/object:Gem::Version
303
+ version: '0'
304
+ - !ruby/object:Gem::Dependency
305
+ name: ruby_gntp
306
+ requirement: !ruby/object:Gem::Requirement
307
+ none: false
308
+ requirements:
309
+ - - ! '>='
310
+ - !ruby/object:Gem::Version
311
+ version: '0'
312
+ type: :development
313
+ prerelease: false
314
+ version_requirements: !ruby/object:Gem::Requirement
315
+ none: false
316
+ requirements:
317
+ - - ! '>='
318
+ - !ruby/object:Gem::Version
319
+ version: '0'
214
320
  description: Like Rack is to Rails and Sinatra, Punchblock provides a consistent API
215
321
  on top of several underlying third-party call control protocols.
216
322
  email: punchblock@adhearsion.com
@@ -359,7 +465,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
359
465
  version: '0'
360
466
  segments:
361
467
  - 0
362
- hash: -3970210055497843172
468
+ hash: 2228525083493052617
363
469
  required_rubygems_version: !ruby/object:Gem::Requirement
364
470
  none: false
365
471
  requirements:
@@ -368,7 +474,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
368
474
  version: 1.3.7
369
475
  requirements: []
370
476
  rubyforge_project: punchblock
371
- rubygems_version: 1.8.10
477
+ rubygems_version: 1.8.21
372
478
  signing_key:
373
479
  specification_version: 3
374
480
  summary: Punchblock is a telephony middleware library