punchblock 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
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