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 +8 -0
- data/Rakefile +0 -1
- data/lib/punchblock/translator/asterisk/call.rb +16 -2
- data/lib/punchblock/translator/asterisk/component/input.rb +10 -14
- data/lib/punchblock/version.rb +1 -1
- data/punchblock.gemspec +11 -10
- data/spec/punchblock/protocol_error_spec.rb +8 -8
- data/spec/punchblock/translator/asterisk/call_spec.rb +40 -3
- data/spec/punchblock/translator/asterisk/component/input_spec.rb +168 -177
- metadata +163 -57
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
|
@@ -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
|
|
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
|
-
@
|
|
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
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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
|
-
|
|
32
|
+
begin_initial_timer initial_timeout/1000 unless initial_timeout == -1
|
|
36
33
|
|
|
37
|
-
|
|
34
|
+
component = current_actor
|
|
38
35
|
|
|
39
|
-
|
|
36
|
+
@active = true
|
|
40
37
|
|
|
41
|
-
|
|
42
|
-
|
|
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
|
data/lib/punchblock/version.rb
CHANGED
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>, ["
|
|
26
|
-
s.add_runtime_dependency %q<blather>, [">= 0.
|
|
27
|
-
s.add_runtime_dependency %q<activesupport>, ["
|
|
28
|
-
s.add_runtime_dependency %q<state_machine>, ["
|
|
29
|
-
s.add_runtime_dependency %q<future-resource>, ["
|
|
30
|
-
s.add_runtime_dependency %q<has-guarded-handlers>, ["
|
|
31
|
-
s.add_runtime_dependency %q<celluloid>, [">= 0.
|
|
32
|
-
s.add_runtime_dependency %q<ruby_ami>, ["
|
|
33
|
-
s.add_runtime_dependency %q<ruby_speech>, ["
|
|
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>, ["
|
|
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 => '
|
|
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 => '
|
|
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
|
-
|
|
53
|
-
|
|
54
|
-
|
|
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
|
-
|
|
58
|
-
|
|
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
|
-
|
|
71
|
+
let(:reason) { original_command.complete_event(5).reason }
|
|
61
72
|
|
|
62
|
-
|
|
63
|
-
|
|
73
|
+
describe "receiving DTMF events" do
|
|
74
|
+
before do
|
|
75
|
+
subject.execute
|
|
76
|
+
expected_event
|
|
64
77
|
end
|
|
65
78
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
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
|
-
|
|
75
|
-
|
|
76
|
-
|
|
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
|
-
|
|
80
|
-
|
|
81
|
-
describe "receiving DTMF events" do
|
|
99
|
+
context "when the match is invalid" do
|
|
82
100
|
before do
|
|
83
|
-
|
|
84
|
-
|
|
101
|
+
send_ami_events_for_dtmf 1
|
|
102
|
+
send_ami_events_for_dtmf '#'
|
|
85
103
|
end
|
|
86
104
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
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
|
-
|
|
108
|
-
|
|
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
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
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
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
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
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
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
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
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
|
-
|
|
165
|
-
|
|
166
|
-
|
|
156
|
+
describe 'terminator' do
|
|
157
|
+
pending
|
|
158
|
+
end
|
|
167
159
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
160
|
+
describe 'recognizer' do
|
|
161
|
+
pending
|
|
162
|
+
end
|
|
171
163
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
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
|
-
|
|
194
|
-
|
|
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
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
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
|
-
|
|
203
|
-
|
|
185
|
+
context '-1' do
|
|
186
|
+
let(:original_command_opts) { { :initial_timeout => -1 } }
|
|
204
187
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
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
|
-
|
|
212
|
-
|
|
194
|
+
context 'unset' do
|
|
195
|
+
let(:original_command_opts) { { :initial_timeout => nil } }
|
|
213
196
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
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
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
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
|
-
|
|
246
|
-
|
|
214
|
+
describe 'inter-digit-timeout' do
|
|
215
|
+
context 'a positive number' do
|
|
216
|
+
let(:original_command_opts) { { :inter_digit_timeout => 1000 } }
|
|
247
217
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
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
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
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
|
-
|
|
264
|
-
|
|
237
|
+
context '-1' do
|
|
238
|
+
let(:original_command_opts) { { :inter_digit_timeout => -1 } }
|
|
265
239
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
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
|
-
|
|
275
|
-
|
|
276
|
-
end
|
|
246
|
+
context 'unset' do
|
|
247
|
+
let(:original_command_opts) { { :inter_digit_timeout => nil } }
|
|
277
248
|
|
|
278
|
-
|
|
279
|
-
|
|
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
|
-
|
|
283
|
-
|
|
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.
|
|
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-
|
|
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:
|
|
18
|
+
requirement: !ruby/object:Gem::Requirement
|
|
19
19
|
none: false
|
|
20
20
|
requirements:
|
|
21
|
-
- -
|
|
21
|
+
- - ~>
|
|
22
22
|
- !ruby/object:Gem::Version
|
|
23
|
-
version:
|
|
23
|
+
version: '1.0'
|
|
24
24
|
type: :runtime
|
|
25
25
|
prerelease: false
|
|
26
|
-
version_requirements:
|
|
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:
|
|
34
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
35
|
none: false
|
|
31
36
|
requirements:
|
|
32
37
|
- - ! '>='
|
|
33
38
|
- !ruby/object:Gem::Version
|
|
34
|
-
version: 0.
|
|
39
|
+
version: 0.7.0
|
|
35
40
|
type: :runtime
|
|
36
41
|
prerelease: false
|
|
37
|
-
version_requirements:
|
|
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:
|
|
50
|
+
requirement: !ruby/object:Gem::Requirement
|
|
41
51
|
none: false
|
|
42
52
|
requirements:
|
|
43
|
-
- -
|
|
53
|
+
- - ~>
|
|
44
54
|
- !ruby/object:Gem::Version
|
|
45
|
-
version:
|
|
55
|
+
version: '3.0'
|
|
46
56
|
type: :runtime
|
|
47
57
|
prerelease: false
|
|
48
|
-
version_requirements:
|
|
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:
|
|
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
|
|
71
|
+
version: '1.0'
|
|
57
72
|
type: :runtime
|
|
58
73
|
prerelease: false
|
|
59
|
-
version_requirements:
|
|
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:
|
|
82
|
+
requirement: !ruby/object:Gem::Requirement
|
|
63
83
|
none: false
|
|
64
84
|
requirements:
|
|
65
|
-
- -
|
|
85
|
+
- - ~>
|
|
66
86
|
- !ruby/object:Gem::Version
|
|
67
|
-
version:
|
|
87
|
+
version: '1.0'
|
|
68
88
|
type: :runtime
|
|
69
89
|
prerelease: false
|
|
70
|
-
version_requirements:
|
|
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:
|
|
98
|
+
requirement: !ruby/object:Gem::Requirement
|
|
74
99
|
none: false
|
|
75
100
|
requirements:
|
|
76
|
-
- -
|
|
101
|
+
- - ~>
|
|
77
102
|
- !ruby/object:Gem::Version
|
|
78
|
-
version:
|
|
103
|
+
version: '1.0'
|
|
79
104
|
type: :runtime
|
|
80
105
|
prerelease: false
|
|
81
|
-
version_requirements:
|
|
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:
|
|
114
|
+
requirement: !ruby/object:Gem::Requirement
|
|
85
115
|
none: false
|
|
86
116
|
requirements:
|
|
87
117
|
- - ! '>='
|
|
88
118
|
- !ruby/object:Gem::Version
|
|
89
|
-
version: 0.
|
|
119
|
+
version: 0.10.0
|
|
90
120
|
type: :runtime
|
|
91
121
|
prerelease: false
|
|
92
|
-
version_requirements:
|
|
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:
|
|
130
|
+
requirement: !ruby/object:Gem::Requirement
|
|
96
131
|
none: false
|
|
97
132
|
requirements:
|
|
98
|
-
- -
|
|
133
|
+
- - ~>
|
|
99
134
|
- !ruby/object:Gem::Version
|
|
100
|
-
version:
|
|
135
|
+
version: '1.0'
|
|
101
136
|
type: :runtime
|
|
102
137
|
prerelease: false
|
|
103
|
-
version_requirements:
|
|
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:
|
|
146
|
+
requirement: !ruby/object:Gem::Requirement
|
|
107
147
|
none: false
|
|
108
148
|
requirements:
|
|
109
|
-
- -
|
|
149
|
+
- - ~>
|
|
110
150
|
- !ruby/object:Gem::Version
|
|
111
|
-
version: 0
|
|
151
|
+
version: '1.0'
|
|
112
152
|
type: :runtime
|
|
113
153
|
prerelease: false
|
|
114
|
-
version_requirements:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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.
|
|
477
|
+
rubygems_version: 1.8.21
|
|
372
478
|
signing_key:
|
|
373
479
|
specification_version: 3
|
|
374
480
|
summary: Punchblock is a telephony middleware library
|