adhearsion 2.0.0.rc1 → 2.0.0.rc2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +7 -0
- data/adhearsion.gemspec +1 -1
- data/lib/adhearsion.rb +7 -1
- data/lib/adhearsion/call.rb +3 -3
- data/lib/adhearsion/call_controller.rb +1 -1
- data/lib/adhearsion/call_controller/output.rb +1 -1
- data/lib/adhearsion/calls.rb +27 -50
- data/lib/adhearsion/configuration.rb +3 -2
- data/lib/adhearsion/foundation/exception_handler.rb +2 -2
- data/lib/adhearsion/generators/app/templates/lib/simon_game.rb +5 -9
- data/lib/adhearsion/initializer.rb +1 -1
- data/lib/adhearsion/menu_dsl/menu.rb +1 -1
- data/lib/adhearsion/process.rb +1 -1
- data/lib/adhearsion/punchblock_plugin/initializer.rb +1 -1
- data/lib/adhearsion/version.rb +1 -28
- data/spec/adhearsion/call_controller/record_spec.rb +8 -1
- data/spec/adhearsion/call_controller_spec.rb +9 -2
- data/spec/adhearsion/call_spec.rb +40 -0
- data/spec/adhearsion/calls_spec.rb +89 -20
- data/spec/adhearsion/process_spec.rb +6 -4
- data/spec/adhearsion_spec.rb +10 -0
- data/spec/spec_helper.rb +1 -0
- metadata +66 -66
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
# [develop](https://github.com/adhearsion/adhearsion)
|
2
2
|
|
3
|
+
# [2.0.0.rc2](https://github.com/adhearsion/adhearsion/compare/v2.0.0.rc1...v2.0.0.rc2) - [2012-03-22](https://rubygems.org/gems/adhearsion/versions/2.0.0.rc2)
|
4
|
+
* Bugfix: Exceptions raised in call event handlers no longer kill the call actor
|
5
|
+
* Bugfix: More exceptions handled internally by Adhearsion are logged in an appropriate context
|
6
|
+
* Bugfix/Change: `Adhearsion::Calls` (`Adhearsion.active_calls`) is now an actor for better thread-safety, and mirrors the Hash API more closely.
|
7
|
+
* Bugfix: Calls are now removed from the active call collection and hung up if their actor dies
|
8
|
+
* Bugfix: SimonGame now works using the new `CallController#ask` api
|
9
|
+
|
3
10
|
# [2.0.0.rc1](https://github.com/adhearsion/adhearsion/compare/v2.0.0.beta1...v2.0.0.rc1) - [2012-03-20](https://rubygems.org/gems/adhearsion/versions/2.0.0.rc1)
|
4
11
|
* Change: `CallController#join` now blocks until a corresponding unjoined event is received
|
5
12
|
* Change: `CallController#speak` is now `CallController#say`
|
data/adhearsion.gemspec
CHANGED
@@ -20,7 +20,7 @@ Gem::Specification.new do |s|
|
|
20
20
|
|
21
21
|
# Runtime dependencies
|
22
22
|
s.add_runtime_dependency 'bundler', [">= 1.0.10"]
|
23
|
-
s.add_runtime_dependency 'punchblock', [">= 0.
|
23
|
+
s.add_runtime_dependency 'punchblock', [">= 0.10.0"]
|
24
24
|
s.add_runtime_dependency 'logging', [">= 1.6.1"]
|
25
25
|
s.add_runtime_dependency 'adhearsion-loquacious', [">= 1.9.0"]
|
26
26
|
s.add_runtime_dependency 'activesupport', [">= 3.0.10"]
|
data/lib/adhearsion.rb
CHANGED
@@ -24,6 +24,8 @@ abort "ERROR: You are running Adhearsion on an unsupported version of Ruby (Ruby
|
|
24
24
|
module Adhearsion
|
25
25
|
extend ActiveSupport::Autoload
|
26
26
|
|
27
|
+
Error = Class.new StandardError
|
28
|
+
|
27
29
|
autoload :Process
|
28
30
|
autoload :Call
|
29
31
|
autoload :CallController
|
@@ -79,7 +81,11 @@ module Adhearsion
|
|
79
81
|
end
|
80
82
|
|
81
83
|
def active_calls
|
82
|
-
@calls
|
84
|
+
if @calls && @calls.alive?
|
85
|
+
@calls
|
86
|
+
else
|
87
|
+
@calls = Calls.new
|
88
|
+
end
|
83
89
|
end
|
84
90
|
|
85
91
|
def status
|
data/lib/adhearsion/call.rb
CHANGED
@@ -8,9 +8,9 @@ module Adhearsion
|
|
8
8
|
#
|
9
9
|
class Call
|
10
10
|
|
11
|
-
Hangup = Class.new
|
11
|
+
Hangup = Class.new Adhearsion::Error
|
12
|
+
CommandTimeout = Class.new Adhearsion::Error
|
12
13
|
ExpiredError = Class.new Celluloid::DeadActorError
|
13
|
-
CommandTimeout = Class.new StandardError
|
14
14
|
|
15
15
|
include Celluloid
|
16
16
|
include HasGuardedHandlers
|
@@ -72,7 +72,7 @@ module Adhearsion
|
|
72
72
|
|
73
73
|
def deliver_message(message)
|
74
74
|
logger.debug "Receiving message: #{message.inspect}"
|
75
|
-
trigger_handler :event, message
|
75
|
+
catching_standard_errors { trigger_handler :event, message }
|
76
76
|
end
|
77
77
|
|
78
78
|
alias << deliver_message
|
@@ -113,7 +113,7 @@ module Adhearsion
|
|
113
113
|
yield component if block_given?
|
114
114
|
|
115
115
|
complete_event = component.complete_event
|
116
|
-
raise
|
116
|
+
raise Adhearsion::Error, [complete_event.reason.details, component.inspect].join(": ") if complete_event.reason.is_a? Punchblock::Event::Complete::Error
|
117
117
|
component
|
118
118
|
end
|
119
119
|
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module Adhearsion
|
4
4
|
class CallController
|
5
5
|
module Output
|
6
|
-
PlaybackError = Class.new
|
6
|
+
PlaybackError = Class.new Adhearsion::Error # Represents failure to play audio, such as when the sound file cannot be found
|
7
7
|
|
8
8
|
def say(text, options = {})
|
9
9
|
play_ssml(text, options) || output(:text, text.to_s, options)
|
data/lib/adhearsion/calls.rb
CHANGED
@@ -1,17 +1,12 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
require 'thread'
|
4
|
-
|
5
3
|
module Adhearsion
|
6
4
|
##
|
7
5
|
# This manages the list of calls the Adhearsion service receives
|
8
|
-
class Calls
|
9
|
-
|
6
|
+
class Calls < Hash
|
7
|
+
include Celluloid
|
10
8
|
|
11
|
-
|
12
|
-
@semaphore = Monitor.new
|
13
|
-
@calls = {}
|
14
|
-
end
|
9
|
+
trap_exit :call_died
|
15
10
|
|
16
11
|
def from_offer(offer)
|
17
12
|
Call.new(offer).tap do |call|
|
@@ -20,63 +15,45 @@ module Adhearsion
|
|
20
15
|
end
|
21
16
|
|
22
17
|
def <<(call)
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
self
|
27
|
-
end
|
28
|
-
|
29
|
-
def any?
|
30
|
-
atomically { !calls.empty? }
|
18
|
+
link call
|
19
|
+
self[call.id] = call
|
20
|
+
current_actor
|
31
21
|
end
|
32
22
|
|
33
23
|
def remove_inactive_call(call)
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
def clear!
|
44
|
-
atomically { calls.clear }
|
24
|
+
if call_is_dead?(call) != nil
|
25
|
+
call_id = key call
|
26
|
+
delete call_id if call_id
|
27
|
+
elsif call.respond_to?(:id)
|
28
|
+
delete call.id
|
29
|
+
else
|
30
|
+
delete call
|
31
|
+
end
|
45
32
|
end
|
46
33
|
|
47
34
|
def with_tag(tag)
|
48
|
-
|
49
|
-
|
50
|
-
call.tagged_with?(tag) ? calls_with_tag << call : calls_with_tag
|
51
|
-
end
|
35
|
+
find_all do |call|
|
36
|
+
call.tagged_with? tag
|
52
37
|
end
|
53
38
|
end
|
54
39
|
|
55
40
|
def each(&block)
|
56
|
-
|
57
|
-
end
|
58
|
-
|
59
|
-
def each_pair
|
60
|
-
calls.each_pair { |id, call| yield id, call }
|
61
|
-
end
|
62
|
-
|
63
|
-
def to_a
|
64
|
-
calls.values
|
65
|
-
end
|
66
|
-
|
67
|
-
def to_h
|
68
|
-
calls
|
69
|
-
end
|
70
|
-
|
71
|
-
def method_missing(m, *args)
|
72
|
-
atomically { calls.send m.to_sym, *args }
|
41
|
+
values.each(&block)
|
73
42
|
end
|
74
43
|
|
75
44
|
private
|
76
45
|
|
77
|
-
def
|
78
|
-
|
46
|
+
def call_is_dead?(call)
|
47
|
+
!call.alive?
|
48
|
+
rescue NoMethodError
|
79
49
|
end
|
80
50
|
|
51
|
+
def call_died(call, reason)
|
52
|
+
catching_standard_errors do
|
53
|
+
call_id = key call
|
54
|
+
remove_inactive_call call
|
55
|
+
PunchblockPlugin.client.execute_command Punchblock::Command::Hangup, :async => true, :call_id => call_id
|
56
|
+
end
|
57
|
+
end
|
81
58
|
end
|
82
59
|
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module Adhearsion
|
4
4
|
class Configuration
|
5
5
|
|
6
|
-
ConfigurationError = Class.new
|
6
|
+
ConfigurationError = Class.new Adhearsion::Error # Error raised while trying to configure a non existent plugin
|
7
7
|
|
8
8
|
##
|
9
9
|
# Initialize the configuration object
|
@@ -45,7 +45,8 @@ module Adhearsion
|
|
45
45
|
Supported levels (in increasing severity) -- :trace < :debug < :info < :warn < :error < :fatal
|
46
46
|
__
|
47
47
|
outputters ["log/adhearsion.log"], :transform => Proc.new { |val| Array(val) }, :desc => <<-__
|
48
|
-
An array of log outputters to use. The default is to log to stdout and log/adhearsion.log
|
48
|
+
An array of log outputters to use. The default is to log to stdout and log/adhearsion.log.
|
49
|
+
Each item must be either a string to use as a filename, or a valid Logging appender (see http://github.com/TwP/logging)
|
49
50
|
__
|
50
51
|
formatter nil, :desc => <<-__
|
51
52
|
A log formatter to apply to all active outputters. If nil, the Adhearsion default formatter will be used.
|
@@ -1,11 +1,11 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
class Object
|
4
|
-
def catching_standard_errors(&block)
|
4
|
+
def catching_standard_errors(l = logger, &block)
|
5
5
|
begin
|
6
6
|
yield
|
7
7
|
rescue StandardError => e
|
8
|
-
Adhearsion::Events.trigger :exception, e
|
8
|
+
Adhearsion::Events.trigger :exception, [e, l]
|
9
9
|
end
|
10
10
|
end
|
11
11
|
end
|
@@ -5,7 +5,7 @@ class SimonGame < Adhearsion::CallController
|
|
5
5
|
answer
|
6
6
|
reset
|
7
7
|
loop do
|
8
|
-
|
8
|
+
update_number
|
9
9
|
collect_attempt
|
10
10
|
verify_attempt
|
11
11
|
end
|
@@ -19,20 +19,16 @@ class SimonGame < Adhearsion::CallController
|
|
19
19
|
@number << random_number
|
20
20
|
end
|
21
21
|
|
22
|
-
def say_number
|
23
|
-
update_number
|
24
|
-
say @number
|
25
|
-
end
|
26
|
-
|
27
22
|
def collect_attempt
|
28
|
-
|
23
|
+
result = ask @number, :limit => @number.length
|
24
|
+
@attempt = result.response
|
29
25
|
end
|
30
26
|
|
31
27
|
def verify_attempt
|
32
28
|
if attempt_correct?
|
33
|
-
|
29
|
+
speak 'good'
|
34
30
|
else
|
35
|
-
|
31
|
+
speak "#{@number.length - 1} times wrong, try again smarty"
|
36
32
|
reset
|
37
33
|
end
|
38
34
|
end
|
@@ -8,7 +8,7 @@ module Adhearsion
|
|
8
8
|
DEFAULT_MAX_NUMBER_OF_TRIES = 1
|
9
9
|
DEFAULT_TIMEOUT = 5
|
10
10
|
|
11
|
-
InvalidStructureError = Class.new
|
11
|
+
InvalidStructureError = Class.new Adhearsion::Error
|
12
12
|
|
13
13
|
attr_reader :builder, :timeout, :tries_count, :max_number_of_tries, :terminator, :limit, :interruptible, :status
|
14
14
|
|
data/lib/adhearsion/process.rb
CHANGED
@@ -150,7 +150,7 @@ module Adhearsion
|
|
150
150
|
end
|
151
151
|
|
152
152
|
def dispatch_call_event(event)
|
153
|
-
if call = Adhearsion.active_calls
|
153
|
+
if call = Adhearsion.active_calls[event.call_id]
|
154
154
|
call.deliver_message! event
|
155
155
|
else
|
156
156
|
logger.error "Event received for inactive call #{event.call_id}: #{event.inspect}"
|
data/lib/adhearsion/version.rb
CHANGED
@@ -1,32 +1,5 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
module Adhearsion #:nodoc:
|
4
|
-
VERSION = '2.0.0.
|
5
|
-
|
6
|
-
class PkgVersion
|
7
|
-
include Comparable
|
8
|
-
|
9
|
-
attr_reader :major, :minor, :revision
|
10
|
-
|
11
|
-
def initialize(version = nil)
|
12
|
-
version ||= ""
|
13
|
-
@major, @minor, @revision, @patchlevel = version.split(".", 4).map(&:to_i)
|
14
|
-
@major = 0 unless @major
|
15
|
-
end
|
16
|
-
|
17
|
-
def <=>(other)
|
18
|
-
return @major <=> other.major unless (@major <=> other.major) == 0
|
19
|
-
return @minor <=> other.minor unless (@minor <=> other.minor) == 0
|
20
|
-
return @revision <=> other.revision unless (@revision <=> other.revision) == 0
|
21
|
-
return 0
|
22
|
-
end
|
23
|
-
|
24
|
-
def self.sort
|
25
|
-
self.sort! { |a,b| a <=> b }
|
26
|
-
end
|
27
|
-
|
28
|
-
def to_s
|
29
|
-
"#{@major}.#{@minor}.#{@revision}"
|
30
|
-
end
|
31
|
-
end
|
4
|
+
VERSION = '2.0.0.rc2'
|
32
5
|
end
|
@@ -43,12 +43,19 @@ module Adhearsion
|
|
43
43
|
end
|
44
44
|
|
45
45
|
it "should pass the exception to the events system" do
|
46
|
-
|
46
|
+
latch = CountDownLatch.new 1
|
47
|
+
Adhearsion::Events.exception do |e, l|
|
48
|
+
e.should be_a TestException
|
49
|
+
l.should be subject.logger
|
50
|
+
latch.countdown!
|
51
|
+
end
|
47
52
|
expect_component_execution component
|
48
53
|
subject.record { |rec| raise TestException }
|
49
54
|
component.request!
|
50
55
|
component.execute!
|
51
56
|
component.trigger_event_handler response
|
57
|
+
latch.wait(1).should be true
|
58
|
+
Adhearsion::Events.clear_handlers :exception
|
52
59
|
end
|
53
60
|
end
|
54
61
|
|
@@ -354,7 +354,7 @@ module Adhearsion
|
|
354
354
|
let(:details) { "Oh noes, it's all borked" }
|
355
355
|
|
356
356
|
it "raises the error" do
|
357
|
-
lambda { subject.execute_component_and_await_completion component }.should raise_error(
|
357
|
+
lambda { subject.execute_component_and_await_completion component }.should raise_error(Adhearsion::Error, "#{details}: #{component}")
|
358
358
|
end
|
359
359
|
end
|
360
360
|
|
@@ -424,8 +424,15 @@ describe ExampleCallController do
|
|
424
424
|
it "should capture errors in callbacks" do
|
425
425
|
subject.should_receive(:setup_models).and_raise StandardError
|
426
426
|
subject.should_receive(:clean_up_models).and_raise StandardError
|
427
|
-
|
427
|
+
latch = CountDownLatch.new 4
|
428
|
+
Adhearsion::Events.exception do |e, l|
|
429
|
+
e.should be_a StandardError
|
430
|
+
l.should be subject.logger
|
431
|
+
latch.countdown!
|
432
|
+
end
|
428
433
|
subject.execute!
|
434
|
+
latch.wait(1).should be true
|
435
|
+
Adhearsion::Events.clear_handlers :exception
|
429
436
|
end
|
430
437
|
|
431
438
|
describe "when the controller finishes without a hangup" do
|
@@ -2,6 +2,12 @@
|
|
2
2
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
|
+
class BrokenController < Adhearsion::CallController
|
6
|
+
def run
|
7
|
+
raise "Blat!"
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
5
11
|
module Adhearsion
|
6
12
|
describe Call do
|
7
13
|
let(:mock_client) { flexmock('Client').tap(&:should_ignore_missing) }
|
@@ -117,6 +123,28 @@ module Adhearsion
|
|
117
123
|
subject << event
|
118
124
|
end
|
119
125
|
end
|
126
|
+
|
127
|
+
context "when raising an exception" do
|
128
|
+
it "does not kill the call actor" do
|
129
|
+
subject.register_event_handler { |e| raise 'foo' }
|
130
|
+
lambda { subject << :foo }.should_not raise_error
|
131
|
+
sleep 1
|
132
|
+
subject.should be_alive
|
133
|
+
end
|
134
|
+
|
135
|
+
it 'passes the exception through the Events system' do
|
136
|
+
latch = CountDownLatch.new 1
|
137
|
+
Adhearsion::Events.exception do |e, l|
|
138
|
+
e.should be_a RuntimeError
|
139
|
+
l.should be subject.logger
|
140
|
+
latch.countdown!
|
141
|
+
end
|
142
|
+
subject.register_event_handler { |e| raise 'foo' }
|
143
|
+
lambda { subject << :foo }.should_not raise_error
|
144
|
+
latch.wait(3).should be true
|
145
|
+
Adhearsion::Events.clear_handlers :exception
|
146
|
+
end
|
147
|
+
end
|
120
148
|
end
|
121
149
|
|
122
150
|
describe "#<<" do
|
@@ -605,6 +633,18 @@ module Adhearsion
|
|
605
633
|
controller_thread = subject.execute_controller mock_controller, latch
|
606
634
|
Adhearsion::Process.important_threads.should include controller_thread
|
607
635
|
end
|
636
|
+
|
637
|
+
it "should pass the exception to the events system" do
|
638
|
+
latch = CountDownLatch.new 1
|
639
|
+
Adhearsion::Events.exception do |e, l|
|
640
|
+
e.should be_a RuntimeError
|
641
|
+
l.should be subject.logger
|
642
|
+
latch.countdown!
|
643
|
+
end
|
644
|
+
subject.execute_controller BrokenController.new(subject), latch
|
645
|
+
latch.wait(3).should be true
|
646
|
+
Adhearsion::Events.clear_handlers :exception
|
647
|
+
end
|
608
648
|
end
|
609
649
|
|
610
650
|
describe "#register_controller" do
|
@@ -4,44 +4,70 @@ require 'spec_helper'
|
|
4
4
|
|
5
5
|
module Adhearsion
|
6
6
|
describe Calls do
|
7
|
-
before { Adhearsion.active_calls.clear! }
|
8
|
-
|
9
7
|
let(:call) { Adhearsion::Call.new new_offer }
|
10
8
|
|
9
|
+
let(:number_of_calls) { 10 }
|
10
|
+
let :calls do
|
11
|
+
Array.new(number_of_calls) { Adhearsion::Call.new new_offer }
|
12
|
+
end
|
13
|
+
|
11
14
|
def new_offer(call_id = nil, headers = {})
|
12
|
-
Punchblock::Event::Offer.new :call_id => call_id ||
|
15
|
+
Punchblock::Event::Offer.new :call_id => call_id || random_call_id, :headers => headers
|
13
16
|
end
|
14
17
|
|
15
|
-
it 'can create a call and add it to the
|
16
|
-
|
17
|
-
call =
|
18
|
+
it 'can create a call and add it to the collection' do
|
19
|
+
subject.any?.should be == false
|
20
|
+
call = subject.from_offer new_offer
|
18
21
|
call.should be_a Adhearsion::Call
|
19
|
-
|
22
|
+
subject.size.should be == 1
|
23
|
+
subject[call.id].should be call
|
20
24
|
end
|
21
25
|
|
22
|
-
it '#size should return the
|
26
|
+
it '#size should return the number of calls in the collection' do
|
23
27
|
subject.size.should be == 0
|
24
28
|
subject << call
|
25
29
|
subject.size.should be == 1
|
26
30
|
end
|
27
31
|
|
28
|
-
|
29
|
-
number_of_calls
|
30
|
-
calls = Array.new(number_of_calls) { Adhearsion::Call.new new_offer }
|
31
|
-
calls.each { |call| subject << call }
|
32
|
+
describe "removing a call" do
|
33
|
+
let(:deleted_call) { calls[number_of_calls / 2] }
|
32
34
|
|
33
|
-
|
34
|
-
subject.remove_inactive_call deleted_call
|
35
|
-
subject.size.should be == number_of_calls - 1
|
36
|
-
end
|
35
|
+
before { calls.each { |call| subject << call } }
|
37
36
|
|
38
|
-
|
39
|
-
|
40
|
-
|
37
|
+
context "by call object" do
|
38
|
+
before { subject.remove_inactive_call deleted_call }
|
39
|
+
|
40
|
+
it "should remove the call from the collection" do
|
41
|
+
subject.size.should be == number_of_calls - 1
|
42
|
+
subject[deleted_call.id].should be_nil
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context "by dead call object" do
|
47
|
+
before do
|
48
|
+
@call_id = deleted_call.id
|
49
|
+
deleted_call.terminate
|
50
|
+
deleted_call.should_not be_alive
|
51
|
+
subject.remove_inactive_call deleted_call
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should remove the call from the collection" do
|
55
|
+
subject.size.should be == number_of_calls - 1
|
56
|
+
subject[@call_id].should be_nil
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context "by ID" do
|
61
|
+
before { subject.remove_inactive_call deleted_call.id }
|
62
|
+
|
63
|
+
it "should remove the call from the collection" do
|
64
|
+
subject.size.should be == number_of_calls - 1
|
65
|
+
subject[deleted_call.id].should be_nil
|
66
|
+
end
|
67
|
+
end
|
41
68
|
end
|
42
69
|
|
43
70
|
it "finding calls by a tag" do
|
44
|
-
calls = Array.new(3) { Adhearsion::Call.new new_offer }
|
45
71
|
calls.each { |call| subject << call }
|
46
72
|
|
47
73
|
tagged_call = calls.last
|
@@ -56,5 +82,48 @@ module Adhearsion
|
|
56
82
|
subject.size.should be == 2
|
57
83
|
end
|
58
84
|
end
|
85
|
+
|
86
|
+
describe "when a call in the collection crashes" do
|
87
|
+
let(:wrapped_object) { call.wrapped_object }
|
88
|
+
|
89
|
+
before do
|
90
|
+
def wrapped_object.crash_me
|
91
|
+
raise StandardError, "Someone crashed me"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def crash
|
96
|
+
lambda { call.crash_me }.should raise_error(StandardError, "Someone crashed me")
|
97
|
+
sleep 0.5
|
98
|
+
end
|
99
|
+
|
100
|
+
it "is removed from the collection" do
|
101
|
+
call_id = call.id
|
102
|
+
size_before = subject.size
|
103
|
+
|
104
|
+
subject << call
|
105
|
+
subject.size.should be > size_before
|
106
|
+
subject[call_id].should be call
|
107
|
+
|
108
|
+
crash
|
109
|
+
subject.size.should be == size_before
|
110
|
+
subject[call_id].should be_nil
|
111
|
+
end
|
112
|
+
|
113
|
+
it "is sends a hangup command for the call" do
|
114
|
+
call_id = call.id
|
115
|
+
flexmock PunchblockPlugin, :client => flexmock('Client')
|
116
|
+
flexmock(PunchblockPlugin.client).should_receive(:execute_command).once.with(Punchblock::Command::Hangup, :async => true, :call_id => call_id)
|
117
|
+
|
118
|
+
subject << call
|
119
|
+
|
120
|
+
crash
|
121
|
+
end
|
122
|
+
|
123
|
+
it "shuts down the actor" do
|
124
|
+
crash
|
125
|
+
call.should_not be_alive
|
126
|
+
end
|
127
|
+
end
|
59
128
|
end
|
60
129
|
end
|
@@ -5,7 +5,7 @@ require 'spec_helper'
|
|
5
5
|
module Adhearsion
|
6
6
|
describe Adhearsion::Process do
|
7
7
|
before :all do
|
8
|
-
Adhearsion.active_calls.clear
|
8
|
+
Adhearsion.active_calls.clear
|
9
9
|
end
|
10
10
|
|
11
11
|
before :each do
|
@@ -17,6 +17,7 @@ module Adhearsion
|
|
17
17
|
flexmock(Events).should_receive(:trigger_immediately).once.with(:shutdown).ordered
|
18
18
|
Adhearsion::Process.booted
|
19
19
|
Adhearsion::Process.shutdown
|
20
|
+
sleep 0.2
|
20
21
|
end
|
21
22
|
|
22
23
|
it '#stop_when_zero_calls should wait until the list of active calls reaches 0' do
|
@@ -48,14 +49,14 @@ module Adhearsion
|
|
48
49
|
describe "#final_shutdown" do
|
49
50
|
it "should hang up active calls" do
|
50
51
|
3.times do
|
51
|
-
fake_call = flexmock
|
52
|
-
flexmock(fake_call).should_receive(:hangup).once
|
52
|
+
fake_call = flexmock Call.new, :id => random_call_id
|
53
|
+
flexmock(fake_call).should_receive(:hangup!).once
|
53
54
|
Adhearsion.active_calls << fake_call
|
54
55
|
end
|
55
56
|
|
56
57
|
Adhearsion::Process.final_shutdown
|
57
58
|
|
58
|
-
Adhearsion.active_calls.clear
|
59
|
+
Adhearsion.active_calls.clear
|
59
60
|
end
|
60
61
|
|
61
62
|
it "should trigger shutdown handlers synchronously" do
|
@@ -89,6 +90,7 @@ module Adhearsion
|
|
89
90
|
Adhearsion::Process.state_name.should be :stopped
|
90
91
|
flexmock(Adhearsion::Process.instance).should_receive(:die_now!).once
|
91
92
|
Adhearsion::Process.shutdown
|
93
|
+
sleep 0.2
|
92
94
|
end
|
93
95
|
|
94
96
|
it 'should forcibly kill the Adhearsion process on :force_stop' do
|
data/spec/adhearsion_spec.rb
CHANGED
@@ -61,6 +61,16 @@ describe Adhearsion do
|
|
61
61
|
it "should return the same instance each time" do
|
62
62
|
Adhearsion.active_calls.should be Adhearsion.active_calls
|
63
63
|
end
|
64
|
+
|
65
|
+
it "should create a new collection if the existing one dies" do
|
66
|
+
original = Adhearsion.active_calls
|
67
|
+
original.terminate
|
68
|
+
original.should_not be_alive
|
69
|
+
|
70
|
+
current = Adhearsion.active_calls
|
71
|
+
current.should be_alive
|
72
|
+
current.should_not be original
|
73
|
+
end
|
64
74
|
end
|
65
75
|
|
66
76
|
describe "#status" do
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: adhearsion
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.0.
|
4
|
+
version: 2.0.0.rc2
|
5
5
|
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -12,11 +12,11 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date: 2012-03-
|
15
|
+
date: 2012-03-22 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: bundler
|
19
|
-
requirement: &
|
19
|
+
requirement: &2156226700 !ruby/object:Gem::Requirement
|
20
20
|
none: false
|
21
21
|
requirements:
|
22
22
|
- - ! '>='
|
@@ -24,21 +24,21 @@ dependencies:
|
|
24
24
|
version: 1.0.10
|
25
25
|
type: :runtime
|
26
26
|
prerelease: false
|
27
|
-
version_requirements: *
|
27
|
+
version_requirements: *2156226700
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
29
|
name: punchblock
|
30
|
-
requirement: &
|
30
|
+
requirement: &2156221520 !ruby/object:Gem::Requirement
|
31
31
|
none: false
|
32
32
|
requirements:
|
33
33
|
- - ! '>='
|
34
34
|
- !ruby/object:Gem::Version
|
35
|
-
version: 0.
|
35
|
+
version: 0.10.0
|
36
36
|
type: :runtime
|
37
37
|
prerelease: false
|
38
|
-
version_requirements: *
|
38
|
+
version_requirements: *2156221520
|
39
39
|
- !ruby/object:Gem::Dependency
|
40
40
|
name: logging
|
41
|
-
requirement: &
|
41
|
+
requirement: &2156220200 !ruby/object:Gem::Requirement
|
42
42
|
none: false
|
43
43
|
requirements:
|
44
44
|
- - ! '>='
|
@@ -46,10 +46,10 @@ dependencies:
|
|
46
46
|
version: 1.6.1
|
47
47
|
type: :runtime
|
48
48
|
prerelease: false
|
49
|
-
version_requirements: *
|
49
|
+
version_requirements: *2156220200
|
50
50
|
- !ruby/object:Gem::Dependency
|
51
51
|
name: adhearsion-loquacious
|
52
|
-
requirement: &
|
52
|
+
requirement: &2156218540 !ruby/object:Gem::Requirement
|
53
53
|
none: false
|
54
54
|
requirements:
|
55
55
|
- - ! '>='
|
@@ -57,10 +57,10 @@ dependencies:
|
|
57
57
|
version: 1.9.0
|
58
58
|
type: :runtime
|
59
59
|
prerelease: false
|
60
|
-
version_requirements: *
|
60
|
+
version_requirements: *2156218540
|
61
61
|
- !ruby/object:Gem::Dependency
|
62
62
|
name: activesupport
|
63
|
-
requirement: &
|
63
|
+
requirement: &2156217580 !ruby/object:Gem::Requirement
|
64
64
|
none: false
|
65
65
|
requirements:
|
66
66
|
- - ! '>='
|
@@ -68,10 +68,10 @@ dependencies:
|
|
68
68
|
version: 3.0.10
|
69
69
|
type: :runtime
|
70
70
|
prerelease: false
|
71
|
-
version_requirements: *
|
71
|
+
version_requirements: *2156217580
|
72
72
|
- !ruby/object:Gem::Dependency
|
73
73
|
name: i18n
|
74
|
-
requirement: &
|
74
|
+
requirement: &2156213900 !ruby/object:Gem::Requirement
|
75
75
|
none: false
|
76
76
|
requirements:
|
77
77
|
- - ! '>='
|
@@ -79,10 +79,10 @@ dependencies:
|
|
79
79
|
version: 0.5.0
|
80
80
|
type: :runtime
|
81
81
|
prerelease: false
|
82
|
-
version_requirements: *
|
82
|
+
version_requirements: *2156213900
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: json
|
85
|
-
requirement: &
|
85
|
+
requirement: &2156213080 !ruby/object:Gem::Requirement
|
86
86
|
none: false
|
87
87
|
requirements:
|
88
88
|
- - ! '>='
|
@@ -90,10 +90,10 @@ dependencies:
|
|
90
90
|
version: '0'
|
91
91
|
type: :runtime
|
92
92
|
prerelease: false
|
93
|
-
version_requirements: *
|
93
|
+
version_requirements: *2156213080
|
94
94
|
- !ruby/object:Gem::Dependency
|
95
95
|
name: thor
|
96
|
-
requirement: &
|
96
|
+
requirement: &2156212120 !ruby/object:Gem::Requirement
|
97
97
|
none: false
|
98
98
|
requirements:
|
99
99
|
- - ! '>='
|
@@ -101,10 +101,10 @@ dependencies:
|
|
101
101
|
version: '0'
|
102
102
|
type: :runtime
|
103
103
|
prerelease: false
|
104
|
-
version_requirements: *
|
104
|
+
version_requirements: *2156212120
|
105
105
|
- !ruby/object:Gem::Dependency
|
106
106
|
name: rake
|
107
|
-
requirement: &
|
107
|
+
requirement: &2156211580 !ruby/object:Gem::Requirement
|
108
108
|
none: false
|
109
109
|
requirements:
|
110
110
|
- - ! '>='
|
@@ -112,10 +112,10 @@ dependencies:
|
|
112
112
|
version: '0'
|
113
113
|
type: :runtime
|
114
114
|
prerelease: false
|
115
|
-
version_requirements: *
|
115
|
+
version_requirements: *2156211580
|
116
116
|
- !ruby/object:Gem::Dependency
|
117
117
|
name: pry
|
118
|
-
requirement: &
|
118
|
+
requirement: &2156210340 !ruby/object:Gem::Requirement
|
119
119
|
none: false
|
120
120
|
requirements:
|
121
121
|
- - ! '>='
|
@@ -123,10 +123,10 @@ dependencies:
|
|
123
123
|
version: '0'
|
124
124
|
type: :runtime
|
125
125
|
prerelease: false
|
126
|
-
version_requirements: *
|
126
|
+
version_requirements: *2156210340
|
127
127
|
- !ruby/object:Gem::Dependency
|
128
128
|
name: uuid
|
129
|
-
requirement: &
|
129
|
+
requirement: &2156209660 !ruby/object:Gem::Requirement
|
130
130
|
none: false
|
131
131
|
requirements:
|
132
132
|
- - ! '>='
|
@@ -134,10 +134,10 @@ dependencies:
|
|
134
134
|
version: '0'
|
135
135
|
type: :runtime
|
136
136
|
prerelease: false
|
137
|
-
version_requirements: *
|
137
|
+
version_requirements: *2156209660
|
138
138
|
- !ruby/object:Gem::Dependency
|
139
139
|
name: future-resource
|
140
|
-
requirement: &
|
140
|
+
requirement: &2156208320 !ruby/object:Gem::Requirement
|
141
141
|
none: false
|
142
142
|
requirements:
|
143
143
|
- - ! '>='
|
@@ -145,10 +145,10 @@ dependencies:
|
|
145
145
|
version: 0.0.2
|
146
146
|
type: :runtime
|
147
147
|
prerelease: false
|
148
|
-
version_requirements: *
|
148
|
+
version_requirements: *2156208320
|
149
149
|
- !ruby/object:Gem::Dependency
|
150
150
|
name: ruby_speech
|
151
|
-
requirement: &
|
151
|
+
requirement: &2156207180 !ruby/object:Gem::Requirement
|
152
152
|
none: false
|
153
153
|
requirements:
|
154
154
|
- - ! '>='
|
@@ -156,10 +156,10 @@ dependencies:
|
|
156
156
|
version: 0.4.0
|
157
157
|
type: :runtime
|
158
158
|
prerelease: false
|
159
|
-
version_requirements: *
|
159
|
+
version_requirements: *2156207180
|
160
160
|
- !ruby/object:Gem::Dependency
|
161
161
|
name: countdownlatch
|
162
|
-
requirement: &
|
162
|
+
requirement: &2156193500 !ruby/object:Gem::Requirement
|
163
163
|
none: false
|
164
164
|
requirements:
|
165
165
|
- - ! '>='
|
@@ -167,10 +167,10 @@ dependencies:
|
|
167
167
|
version: '0'
|
168
168
|
type: :runtime
|
169
169
|
prerelease: false
|
170
|
-
version_requirements: *
|
170
|
+
version_requirements: *2156193500
|
171
171
|
- !ruby/object:Gem::Dependency
|
172
172
|
name: has-guarded-handlers
|
173
|
-
requirement: &
|
173
|
+
requirement: &2156188320 !ruby/object:Gem::Requirement
|
174
174
|
none: false
|
175
175
|
requirements:
|
176
176
|
- - ! '>='
|
@@ -178,10 +178,10 @@ dependencies:
|
|
178
178
|
version: 1.1.0
|
179
179
|
type: :runtime
|
180
180
|
prerelease: false
|
181
|
-
version_requirements: *
|
181
|
+
version_requirements: *2156188320
|
182
182
|
- !ruby/object:Gem::Dependency
|
183
183
|
name: girl_friday
|
184
|
-
requirement: &
|
184
|
+
requirement: &2156187600 !ruby/object:Gem::Requirement
|
185
185
|
none: false
|
186
186
|
requirements:
|
187
187
|
- - ! '>='
|
@@ -189,10 +189,10 @@ dependencies:
|
|
189
189
|
version: '0'
|
190
190
|
type: :runtime
|
191
191
|
prerelease: false
|
192
|
-
version_requirements: *
|
192
|
+
version_requirements: *2156187600
|
193
193
|
- !ruby/object:Gem::Dependency
|
194
194
|
name: ffi
|
195
|
-
requirement: &
|
195
|
+
requirement: &2156186680 !ruby/object:Gem::Requirement
|
196
196
|
none: false
|
197
197
|
requirements:
|
198
198
|
- - ! '>='
|
@@ -200,10 +200,10 @@ dependencies:
|
|
200
200
|
version: 1.0.11
|
201
201
|
type: :runtime
|
202
202
|
prerelease: false
|
203
|
-
version_requirements: *
|
203
|
+
version_requirements: *2156186680
|
204
204
|
- !ruby/object:Gem::Dependency
|
205
205
|
name: celluloid
|
206
|
-
requirement: &
|
206
|
+
requirement: &2156186020 !ruby/object:Gem::Requirement
|
207
207
|
none: false
|
208
208
|
requirements:
|
209
209
|
- - ! '>='
|
@@ -211,10 +211,10 @@ dependencies:
|
|
211
211
|
version: 0.9.0
|
212
212
|
type: :runtime
|
213
213
|
prerelease: false
|
214
|
-
version_requirements: *
|
214
|
+
version_requirements: *2156186020
|
215
215
|
- !ruby/object:Gem::Dependency
|
216
216
|
name: deep_merge
|
217
|
-
requirement: &
|
217
|
+
requirement: &2152014220 !ruby/object:Gem::Requirement
|
218
218
|
none: false
|
219
219
|
requirements:
|
220
220
|
- - ! '>='
|
@@ -222,10 +222,10 @@ dependencies:
|
|
222
222
|
version: '0'
|
223
223
|
type: :runtime
|
224
224
|
prerelease: false
|
225
|
-
version_requirements: *
|
225
|
+
version_requirements: *2152014220
|
226
226
|
- !ruby/object:Gem::Dependency
|
227
227
|
name: rspec
|
228
|
-
requirement: &
|
228
|
+
requirement: &2152012400 !ruby/object:Gem::Requirement
|
229
229
|
none: false
|
230
230
|
requirements:
|
231
231
|
- - ~>
|
@@ -233,10 +233,10 @@ dependencies:
|
|
233
233
|
version: 2.7.0
|
234
234
|
type: :development
|
235
235
|
prerelease: false
|
236
|
-
version_requirements: *
|
236
|
+
version_requirements: *2152012400
|
237
237
|
- !ruby/object:Gem::Dependency
|
238
238
|
name: flexmock
|
239
|
-
requirement: &
|
239
|
+
requirement: &2152011380 !ruby/object:Gem::Requirement
|
240
240
|
none: false
|
241
241
|
requirements:
|
242
242
|
- - ! '>='
|
@@ -244,10 +244,10 @@ dependencies:
|
|
244
244
|
version: '0'
|
245
245
|
type: :development
|
246
246
|
prerelease: false
|
247
|
-
version_requirements: *
|
247
|
+
version_requirements: *2152011380
|
248
248
|
- !ruby/object:Gem::Dependency
|
249
249
|
name: activerecord
|
250
|
-
requirement: &
|
250
|
+
requirement: &2152009540 !ruby/object:Gem::Requirement
|
251
251
|
none: false
|
252
252
|
requirements:
|
253
253
|
- - ! '>='
|
@@ -255,10 +255,10 @@ dependencies:
|
|
255
255
|
version: 3.0.10
|
256
256
|
type: :development
|
257
257
|
prerelease: false
|
258
|
-
version_requirements: *
|
258
|
+
version_requirements: *2152009540
|
259
259
|
- !ruby/object:Gem::Dependency
|
260
260
|
name: simplecov
|
261
|
-
requirement: &
|
261
|
+
requirement: &2152008640 !ruby/object:Gem::Requirement
|
262
262
|
none: false
|
263
263
|
requirements:
|
264
264
|
- - ! '>='
|
@@ -266,10 +266,10 @@ dependencies:
|
|
266
266
|
version: '0'
|
267
267
|
type: :development
|
268
268
|
prerelease: false
|
269
|
-
version_requirements: *
|
269
|
+
version_requirements: *2152008640
|
270
270
|
- !ruby/object:Gem::Dependency
|
271
271
|
name: simplecov-rcov
|
272
|
-
requirement: &
|
272
|
+
requirement: &2152007400 !ruby/object:Gem::Requirement
|
273
273
|
none: false
|
274
274
|
requirements:
|
275
275
|
- - ! '>='
|
@@ -277,10 +277,10 @@ dependencies:
|
|
277
277
|
version: '0'
|
278
278
|
type: :development
|
279
279
|
prerelease: false
|
280
|
-
version_requirements: *
|
280
|
+
version_requirements: *2152007400
|
281
281
|
- !ruby/object:Gem::Dependency
|
282
282
|
name: ci_reporter
|
283
|
-
requirement: &
|
283
|
+
requirement: &2152006220 !ruby/object:Gem::Requirement
|
284
284
|
none: false
|
285
285
|
requirements:
|
286
286
|
- - ! '>='
|
@@ -288,10 +288,10 @@ dependencies:
|
|
288
288
|
version: '0'
|
289
289
|
type: :development
|
290
290
|
prerelease: false
|
291
|
-
version_requirements: *
|
291
|
+
version_requirements: *2152006220
|
292
292
|
- !ruby/object:Gem::Dependency
|
293
293
|
name: yard
|
294
|
-
requirement: &
|
294
|
+
requirement: &2156172140 !ruby/object:Gem::Requirement
|
295
295
|
none: false
|
296
296
|
requirements:
|
297
297
|
- - ! '>='
|
@@ -299,10 +299,10 @@ dependencies:
|
|
299
299
|
version: '0'
|
300
300
|
type: :development
|
301
301
|
prerelease: false
|
302
|
-
version_requirements: *
|
302
|
+
version_requirements: *2156172140
|
303
303
|
- !ruby/object:Gem::Dependency
|
304
304
|
name: guard-rspec
|
305
|
-
requirement: &
|
305
|
+
requirement: &2156170840 !ruby/object:Gem::Requirement
|
306
306
|
none: false
|
307
307
|
requirements:
|
308
308
|
- - ! '>='
|
@@ -310,10 +310,10 @@ dependencies:
|
|
310
310
|
version: '0'
|
311
311
|
type: :development
|
312
312
|
prerelease: false
|
313
|
-
version_requirements: *
|
313
|
+
version_requirements: *2156170840
|
314
314
|
- !ruby/object:Gem::Dependency
|
315
315
|
name: guard-cucumber
|
316
|
-
requirement: &
|
316
|
+
requirement: &2156169560 !ruby/object:Gem::Requirement
|
317
317
|
none: false
|
318
318
|
requirements:
|
319
319
|
- - ! '>='
|
@@ -321,10 +321,10 @@ dependencies:
|
|
321
321
|
version: '0'
|
322
322
|
type: :development
|
323
323
|
prerelease: false
|
324
|
-
version_requirements: *
|
324
|
+
version_requirements: *2156169560
|
325
325
|
- !ruby/object:Gem::Dependency
|
326
326
|
name: ruby_gntp
|
327
|
-
requirement: &
|
327
|
+
requirement: &2156167960 !ruby/object:Gem::Requirement
|
328
328
|
none: false
|
329
329
|
requirements:
|
330
330
|
- - ! '>='
|
@@ -332,10 +332,10 @@ dependencies:
|
|
332
332
|
version: '0'
|
333
333
|
type: :development
|
334
334
|
prerelease: false
|
335
|
-
version_requirements: *
|
335
|
+
version_requirements: *2156167960
|
336
336
|
- !ruby/object:Gem::Dependency
|
337
337
|
name: cucumber
|
338
|
-
requirement: &
|
338
|
+
requirement: &2156120960 !ruby/object:Gem::Requirement
|
339
339
|
none: false
|
340
340
|
requirements:
|
341
341
|
- - ! '>='
|
@@ -343,10 +343,10 @@ dependencies:
|
|
343
343
|
version: '0'
|
344
344
|
type: :development
|
345
345
|
prerelease: false
|
346
|
-
version_requirements: *
|
346
|
+
version_requirements: *2156120960
|
347
347
|
- !ruby/object:Gem::Dependency
|
348
348
|
name: aruba
|
349
|
-
requirement: &
|
349
|
+
requirement: &2156118080 !ruby/object:Gem::Requirement
|
350
350
|
none: false
|
351
351
|
requirements:
|
352
352
|
- - ! '>='
|
@@ -354,7 +354,7 @@ dependencies:
|
|
354
354
|
version: '0'
|
355
355
|
type: :development
|
356
356
|
prerelease: false
|
357
|
-
version_requirements: *
|
357
|
+
version_requirements: *2156118080
|
358
358
|
description: Adhearsion is an open-source telephony development framework
|
359
359
|
email: dev&Adhearsion.com
|
360
360
|
executables:
|
@@ -517,7 +517,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
517
517
|
version: '0'
|
518
518
|
segments:
|
519
519
|
- 0
|
520
|
-
hash: -
|
520
|
+
hash: -2676474875029582124
|
521
521
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
522
522
|
none: false
|
523
523
|
requirements:
|