adhearsion 1.2.4 → 1.2.5

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,14 @@
1
+ support/1.x.x
2
+
3
+ 1.2.5
4
+ - Catch missing exceptions raised in the after_initialized hook
5
+ - Fixed memory leak in logging when lots of calls come in with unique call id's.
6
+ - Fixed bug where we modified the filename variable passed to #record, which could lead to confusion by callers
7
+ - Avoid some bugs on Ruby 1.8 and JRuby
8
+ - Fixed a bug where generated component config files were not loaded
9
+ - Prevent infinite loops when raising exceptions in exception handlers
10
+ - ahn command now avoids issues with mismatch between installed and bundled gems
11
+
1
12
  1.2.4
2
13
  - Backported Thor-based generators from Adhearsion 2 in order to escape Rubigen.
3
14
 
@@ -32,7 +32,7 @@ Gem::Specification.new do |s|
32
32
  s.add_runtime_dependency "pry"
33
33
 
34
34
  # Development dependencies
35
- s.add_development_dependency 'rspec', [">= 2.4.0"]
35
+ s.add_development_dependency 'rspec', [">= 2.4.0", '< 2.8.0']
36
36
  s.add_development_dependency 'flexmock'
37
37
  s.add_development_dependency 'activerecord', [">= 2.1.0"]
38
38
  s.add_development_dependency 'rake'
data/bin/ahn CHANGED
@@ -22,8 +22,6 @@
22
22
  $:.unshift File.expand_path(File.dirname(__FILE__) + "/../lib")
23
23
 
24
24
  require 'rubygems'
25
- require 'bundler/setup'
26
- require 'adhearsion'
27
25
  require 'adhearsion/cli'
28
26
 
29
- Adhearsion::CLI::AhnCommand.execute!
27
+ Adhearsion::CLI::AhnCommand.execute!
@@ -4,4 +4,6 @@ require 'adhearsion/script_ahn_loader'
4
4
  # the rest of this script is not run.
5
5
  Adhearsion::ScriptAhnLoader.exec_script_ahn!
6
6
 
7
+ require 'bundler/setup'
8
+ require 'adhearsion'
7
9
  require 'adhearsion/commands'
@@ -72,20 +72,19 @@ module Adhearsion
72
72
  #
73
73
  def configuration_for_component_named(component_name)
74
74
  # Look for configuration in #{AHN_ROOT}/config/components first
75
- if File.exists?("#{AHN_ROOT}/config/components/#{component_name}.yml")
76
- return YAML.load_file "#{AHN_ROOT}/config/components/#{component_name}.yml"
77
- end
78
-
75
+ # Look for configuration in #{AHN_ROOT}/components/#{component_name}/config next
79
76
  # Next try the local app component directory
80
- component_dir = File.join(@path_to_container_directory, component_name)
81
- config_file = File.join component_dir, "#{component_name}.yml"
82
- if File.exists?(config_file)
83
- YAML.load_file config_file
84
- else
85
- # Nothing found? Return an empty hash
86
- ahn_log.warn "No configuration found for requested component #{component_name}"
87
- return {}
77
+ %W{
78
+ #{AHN_ROOT}/config/components/#{component_name}.yml
79
+ #{AHN_ROOT}/components/#{component_name}/config/#{component_name}.yml
80
+ #{File.join @path_to_container_directory, component_name, "#{component_name}.yml"}
81
+ }.each do |filename|
82
+ return YAML.load_file filename if File.exists?(filename)
88
83
  end
84
+
85
+ # Nothing found? Return an empty hash
86
+ ahn_log.warn "No configuration found for requested component #{component_name}"
87
+ {}
89
88
  end
90
89
 
91
90
  def extend_object_with(object, *scopes)
@@ -2,7 +2,7 @@ module Adhearsion #:nodoc:
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 1 unless defined? MAJOR
4
4
  MINOR = 2 unless defined? MINOR
5
- TINY = 4 unless defined? TINY
5
+ TINY = 5 unless defined? TINY
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.') unless defined? STRING
8
8
  end
@@ -299,7 +299,7 @@ module Adhearsion
299
299
  # by default.
300
300
  #
301
301
  # @param [string] file name to record to. Full path information is optional. If you want to change the
302
- # format of the file you will want to add a .<valid extention> to the end of the file name specifying the
302
+ # format of the file you will want to add a .<valid extention> to the end of the file name specifying the
303
303
  # filetype you want to record in. Alternately you can pass it is as :format in the options
304
304
  #
305
305
  # @param [hash] options
@@ -315,42 +315,37 @@ module Adhearsion
315
315
  # +:format+ - the format of the file to be recorded
316
316
  #
317
317
  # Silence and maxduration is specified in seconds.
318
- #
319
- # @return [String] The filename of the recorded file.
320
- #
318
+ #
319
+ # @return [String] The filename of the recorded file.
320
+ #
321
321
  # @example Asterisk generated filename
322
322
  # filename = record
323
323
  # @example Specified filename
324
324
  # record '/path/to/my-file.gsm'
325
325
  # @example All options specified
326
326
  # record 'my-file.gsm', :silence => 5, :maxduration => 120
327
- #
327
+ #
328
328
  # @deprecated please use {#record_to_file} instead
329
329
  def record(*args)
330
- options = args.last.kind_of?(Hash) ? args.last : {}
331
- filename = args.first && !args.first.kind_of?(Hash) ? String.new(args.first) : "/tmp/recording_%d"
332
- if filename.index("%d")
333
- if @call.variables.has_key?(:recording_counter)
334
- @call.variables[:recording_counter] += 1
335
- else
336
- @call.variables[:recording_counter] = 0
337
- end
338
- filename = filename % @call.variables[:recording_counter]
339
- @call.variables[:recording_counter] -= 1
340
- end
341
-
342
- if (!options.has_key?(:format))
343
- format = filename.slice!(/\.[^\.]+$/)
344
- if (format.nil?)
345
- ahn_log.agi.warn "Format not specified and not detected. Defaulting to \"gsm\""
346
- format = "gsm"
347
- end
348
- format.sub!(/^\./, "")
349
- else
330
+ options = args.last.kind_of?(Hash) ? args.pop : {}
331
+ filename = args.shift || "/tmp/recording_%d"
332
+ filename = increment_filename_counter filename
333
+
334
+ # Work around Ruby 1.8 limitation with *args
335
+ newargs = []
336
+ newargs << filename
337
+ newargs += args
338
+ newargs << options
339
+ record_to_file *newargs
340
+
341
+ # Reconstruct the logic that took place in #base_record_to_file, since it does not return the
342
+ # constructed filename
343
+ if (options.has_key?(:format))
350
344
  format = options[:format]
345
+ else
346
+ filename, format = format_from_filename filename
351
347
  end
352
- record_to_file(*args)
353
- filename + "." + format
348
+ "#{filename}.#{format}"
354
349
  end
355
350
 
356
351
  # Records a sound file with the given name. If no filename is specified a file named by Asterisk
@@ -359,7 +354,7 @@ module Adhearsion
359
354
  # by default.
360
355
  #
361
356
  # @param [string] file name to record to. Full path information is optional. If you want to change the
362
- # format of the file you will want to add a .<valid extention> to the end of the file name specifying the
357
+ # format of the file you will want to add a .<valid extention> to the end of the file name specifying the
363
358
  # filetype you want to record in. If you don't specify a valid extension it will default to gsm and a
364
359
  # .gsm will be added to the file. If you don't specify a filename it will write one in /tmp/recording_%d
365
360
  # with %d being a counter that increments from 0 onward for the particular call you are making.
@@ -377,11 +372,11 @@ module Adhearsion
377
372
  # +:format+ - the format of the file to be recorded. This will over-ride a implicit format in a file extension and append a .<format> to the end of the file.
378
373
  #
379
374
  # Silence and maxduration is specified in seconds.
380
- #
381
- # @return [Symbol] One of the follwing..... :hangup, :write_error, :success_dtmf, :success_timeout
382
- #
375
+ #
376
+ # @return [Symbol] One of the follwing..... :hangup, :write_error, :success_dtmf, :success_timeout
377
+ #
383
378
  # A sound file will be recorded to the specifed file unless a :write_error is returned. A :success_dtmf is
384
- # for when a call was ended with a DTMF tone. A :success_timeout is returned when a call times out due to
379
+ # for when a call was ended with a DTMF tone. A :success_timeout is returned when a call times out due to
385
380
  # a silence longer than the specified silence or if the recording reaches the maxduration.
386
381
  #
387
382
  # @example Asterisk generated filename
@@ -408,12 +403,16 @@ module Adhearsion
408
403
  return_values.first
409
404
  end
410
405
 
411
- # this is a base methor record_to_file and record_to_file! and should only be used via those methods
412
- #
413
- def base_record_to_file(*args)
414
- options = args.last.kind_of?(Hash) ? args.pop : {}
415
- filename = args.shift || "/tmp/recording_#{new_guid}_%d"
406
+ def format_from_filename(filename)
407
+ filename, format = filename.match(/(^.*)\.([^\.]+)$/).captures rescue [filename, nil]
408
+ if (format.nil?)
409
+ ahn_log.agi.warn "Format not specified and not detected. Defaulting to \"gsm\""
410
+ format = "gsm"
411
+ end
412
+ [filename, format]
413
+ end
416
414
 
415
+ def increment_filename_counter(filename)
417
416
  if filename.index("%d")
418
417
  if @call.variables.has_key?(:recording_counter)
419
418
  @call.variables[:recording_counter] += 1
@@ -422,16 +421,21 @@ module Adhearsion
422
421
  end
423
422
  filename = filename % @call.variables[:recording_counter]
424
423
  end
424
+ filename
425
+ end
425
426
 
426
- if (!options.has_key?(:format))
427
- format = filename.slice!(/\.[^\.]+$/)
428
- if (format.nil?)
429
- ahn_log.agi.warn "Format not specified and not detected. Defaulting to \"gsm\""
430
- format = "gsm"
431
- end
432
- format.sub!(/^\./, "")
427
+ # this is a base methor record_to_file and record_to_file! and should only be used via those methods
428
+ #
429
+ def base_record_to_file(*args)
430
+ options = args.last.kind_of?(Hash) ? args.pop : {}
431
+ filename = args.shift || "/tmp/recording_#{new_guid}_%d"
432
+
433
+ filename = increment_filename_counter filename
434
+
435
+ if (options.has_key?(:format))
436
+ format = options[:format]
433
437
  else
434
- format = options.delete(:format)
438
+ filename, format = format_from_filename filename
435
439
  end
436
440
 
437
441
  # maxduration must be in milliseconds when using RECORD FILE
@@ -441,15 +445,15 @@ module Adhearsion
441
445
  escapedigits = options.delete(:escapedigits) || "#"
442
446
  silence = options.delete(:silence) || 0
443
447
 
444
- response_params = filename, format, escapedigits, maxduration, 0
448
+ response_params = filename, format, escapedigits, maxduration, 0
445
449
  response_values = []
446
-
447
- if !options.has_key? :beep
450
+
451
+ if !options.has_key? :beep
448
452
  response_params << 'BEEP'
449
453
  elsif options[:beep]
450
454
  play_soundfile options[:beep]
451
455
  playback_response = get_variable('PLAYBACKSTATUS')
452
- if playback_response != PLAYBACK_SUCCESS
456
+ if playback_response != PLAYBACK_SUCCESS
453
457
  response_values << :playback_error
454
458
  response_values << playback_response
455
459
  end
@@ -465,7 +469,7 @@ module Adhearsion
465
469
  if resp.match /hangup/
466
470
  response_values << :hangup
467
471
  elsif resp.match /writefile/
468
- response_values << :write_error
472
+ response_values << :write_error
469
473
  elsif resp.match /dtmf/
470
474
  response_values << :success_dtmf
471
475
  elsif resp.match /timeout/
@@ -757,6 +761,7 @@ module Adhearsion
757
761
  initial_timeout = options[:initial_timeout] || timeout
758
762
  interdigit_timeout = options[:interdigit_timeout] || timeout
759
763
  terminating_key = options[:accept_key]
764
+ raise ArgumentError, ":accept_key must not be empty" if terminating_key == ""
760
765
  terminating_key = if terminating_key
761
766
  terminating_key.to_s
762
767
  elsif number_of_digits.nil? && !terminating_key.equal?(false)
@@ -298,10 +298,6 @@ module Adhearsion
298
298
  end
299
299
  end
300
300
 
301
- def ahn_log(*args)
302
- Adhearsion::Logging::DefaultAdhearsionLogger.send Adhearsion::Logging::AdhearsionLogger.sanitized_logger_name(unique_identifier), *args
303
- end
304
-
305
301
  def define_variable_accessors(recipient=self)
306
302
  variables.each do |key, value|
307
303
  define_singleton_accessor_with_pair(key, value, recipient)
@@ -93,10 +93,6 @@ module Adhearsion
93
93
  Components.component_manager.extend_object_with(self, :dialplan) if Components.component_manager
94
94
  end
95
95
 
96
- def ahn_log(*args)
97
- @call.ahn_log *args
98
- end
99
-
100
96
  end
101
97
 
102
98
  class Manager
@@ -68,6 +68,7 @@ module Theatre
68
68
  callback.call payload
69
69
  end
70
70
  rescue => captured_error_to_be_returned
71
+ Adhearsion::Events.trigger '/exception', captured_error_to_be_returned
71
72
  captured_error_to_be_returned
72
73
  end
73
74
  end
@@ -136,7 +137,7 @@ module Theatre
136
137
  next_invocation = @master_queue.pop
137
138
  return :stopped if next_invocation.equal? :THEATRE_SHUTDOWN!
138
139
  next_invocation.start
139
- rescue Exception => error
140
+ rescue StandardError => error
140
141
  Adhearsion::Events.trigger(['exception'], error)
141
142
  end
142
143
  end
@@ -22,9 +22,10 @@ module Theatre
22
22
  #
23
23
  def initialize(namespace, callback, payload=:theatre_no_payload)
24
24
  raise ArgumentError, "Callback must be a Proc" unless callback.kind_of? Proc
25
+ @namespace = namespace
26
+ @callback = callback
25
27
  @payload = payload
26
28
  @unique_id = new_guid.freeze
27
- @callback = callback
28
29
  @current_state = :new
29
30
  @state_lock = Mutex.new
30
31
 
@@ -63,6 +64,14 @@ module Theatre
63
64
  end
64
65
  with_state_lock { @current_state = :success }
65
66
  rescue => e
67
+ if Array(@namespace).first =~ /exception/
68
+ # Exception encountered in exception handler. Do not perpetuate the loop.
69
+ ahn_log.error "Exception encountered in exception handler!"
70
+ ahn_log.error e.message
71
+ ahn_log.error e.backtrace.join("\n")
72
+ else
73
+ Adhearsion::Events.trigger('/exception', e)
74
+ end
66
75
  @error = e
67
76
  with_state_lock { @current_state = :error }
68
77
  ensure
@@ -42,9 +42,9 @@ describe 'The ahn_log command' do
42
42
  end
43
43
 
44
44
  it "handles crazy logger names" do
45
- ahn_log.send :'locals@DEMO_ca.ll&', "hey"
46
- Log4r::Logger['locals@DEMO_ca.ll&'].should_not be nil
47
- ahn_log.send(:'localsdemo_call').should == Log4r::Logger['locals@DEMO_ca.ll&']
45
+ ahn_log.send :'locals@DEMO_call&', "hey"
46
+ Log4r::Logger['locals@DEMO_call&'].should_not be nil
47
+ ahn_log.send(:'localsdemo_call').should == Log4r::Logger['locals@DEMO_call&']
48
48
  end
49
49
 
50
50
  end
@@ -29,7 +29,7 @@ module DialplanCommandTestHelpers
29
29
  class MockCall
30
30
  attr_accessor :variables
31
31
 
32
- def initialize
32
+ def initialize
33
33
  @variables = {}
34
34
  end
35
35
 
@@ -284,7 +284,7 @@ describe 'receiving a hangup' do
284
284
  end
285
285
  the_following_code {
286
286
  mock_call.read()
287
- }.should raise_error(Adhearsion::Hangup)
287
+ }.should raise_error(Adhearsion::Hangup)
288
288
  end
289
289
  end
290
290
 
@@ -743,28 +743,33 @@ describe 'the #record method' do
743
743
 
744
744
  it 'create a default filename if no file is specifed and icrement it on subsequent calls' do
745
745
  mock_call.call.variables.delete :recording_counter
746
- mock_call.should_receive(:new_guid).once.and_return('2345')
747
- mock_call.should_receive(:new_guid).once.and_return('4322')
748
- mock_call.should_receive(:response).once.with('RECORD FILE', '/tmp/recording_2345_0', 'gsm', '26', -1, 0).and_return("200 result=0 (timeout) endpos=21600\n")
749
- mock_call.should_receive(:response).once.with('RECORD FILE', '/tmp/recording_4322_1', 'gsm', '26', -1, 0).and_return("200 result=0 (timeout) endpos=21600\n")
746
+ mock_call.should_receive(:response).once.with('RECORD FILE', '/tmp/recording_0', 'gsm', '26', -1, 0).and_return("200 result=0 (timeout) endpos=21600\n")
747
+ mock_call.should_receive(:response).once.with('RECORD FILE', '/tmp/recording_1', 'gsm', '26', -1, 0).and_return("200 result=0 (timeout) endpos=21600\n")
750
748
  mock_call.record(:beep => nil, :escapedigits => '26').should == '/tmp/recording_0.gsm'
751
749
  mock_call.record(:beep => nil, :escapedigits => '26').should == '/tmp/recording_1.gsm'
752
- end
750
+ end
751
+
752
+ it 'should not modify the passed-in file name' do
753
+ mock_call.should_receive(:response).once.with('RECORD FILE', 'foo', 'wav', '#', -1, 0, 'BEEP').and_return("200 result=-1 (hangup) endpos=167840\n")
754
+ filename = 'foo.wav'
755
+ mock_call.record(filename).should == 'foo.wav'
756
+ filename.should == 'foo.wav'
757
+ end
753
758
 
754
759
  it 'determine the format from the filename' do
755
760
  mock_call.should_receive(:response).once.with('RECORD FILE', 'foo', 'wav', '26', -1, 0).and_return("200 result=0 (timeout) endpos=21600\n")
756
761
  mock_call.record('foo.wav', :beep => nil, :escapedigits => '26').should == 'foo.wav'
757
- end
762
+ end
758
763
 
759
764
  it 'set the format of a file via the :format option' do
760
765
  mock_call.should_receive(:response).once.with("RECORD FILE", "foo", "wav", "#", 2000, 0).and_return("200 result=0 (timeout) endpos=21600\n")
761
766
  mock_call.record('foo', :beep => nil, :maxduration => 2, :format => 'wav').should == 'foo.wav'
762
- end
767
+ end
763
768
 
764
769
  it 'set the format of a file via the :format option over-riding a implicit format' do
765
770
  mock_call.should_receive(:response).once.with("RECORD FILE", "foo.wav", "mpeg", "#", 2000, 0).and_return("200 result=0 (timeout) endpos=21600\n")
766
771
  mock_call.record('foo.wav', :beep => nil, :maxduration => 2, :format => 'mpeg').should == 'foo.wav.mpeg'
767
- end
772
+ end
768
773
  end
769
774
 
770
775
  describe 'the #record_to_file method' do
@@ -778,47 +783,47 @@ describe 'the #record_to_file method' do
778
783
  it 'should return :write error if the recording had a problem writing the file' do
779
784
  mock_call.should_receive(:response).once.with("RECORD FILE", "foo", "gsm", "#", -1, 0, "BEEP").and_return("200 result=-1 (writefile) endpos=167840\n")
780
785
  mock_call.record_to_file('foo').should == :write_error
781
- end
786
+ end
782
787
 
783
788
  it 'should return :success_dtmf if the recording was completed successfully with a dtmf tone to end' do
784
789
  mock_call.should_receive(:response).once.with("RECORD FILE", "foo", "gsm", "#", -1, 0, "BEEP").and_return("200 result=35 (dtmf) endpos=29120\n")
785
790
  mock_call.record_to_file('foo').should == :success_dtmf
786
- end
791
+ end
787
792
 
788
793
  it 'should return :success_timeout if the recording was completed successfully by timing out with silence' do
789
794
  mock_call.should_receive(:response).once.with("RECORD FILE", "foo", "gsm", "#", -1, 0, "BEEP").and_return("200 result=0 (timeout) endpos=21600\n")
790
795
  mock_call.record_to_file('foo').should == :success_timeout
791
- end
796
+ end
792
797
 
793
798
  it 'not send a beep if a :beep=>nil is passed in' do
794
799
  mock_call.should_receive(:response).once.with("RECORD FILE", "foo", "gsm", "#", -1, 0).and_return("200 result=0 (timeout) endpos=21600\n")
795
800
  mock_call.record_to_file('foo', :beep => nil).should == :success_timeout
796
- end
801
+ end
797
802
 
798
803
  it 'set the silence if it is passed in' do
799
804
  mock_call.should_receive(:response).once.with("RECORD FILE", "foo", "gsm", "#", -1, 0, 's=2').and_return("200 result=0 (timeout) endpos=21600\n")
800
805
  mock_call.record_to_file('foo', :beep => nil, :silence => 2).should == :success_timeout
801
- end
806
+ end
802
807
 
803
808
  it 'set the maxduration if it is passed in' do
804
809
  mock_call.should_receive(:response).once.with("RECORD FILE", "foo", "gsm", "#", 2000, 0).and_return("200 result=0 (timeout) endpos=21600\n")
805
810
  mock_call.record_to_file('foo', :beep => nil, :maxduration => 2).should == :success_timeout
806
- end
811
+ end
807
812
 
808
813
  it 'set the format of a file via the :format option' do
809
814
  mock_call.should_receive(:response).once.with("RECORD FILE", "foo", "wav", "#", 2000, 0).and_return("200 result=0 (timeout) endpos=21600\n")
810
815
  mock_call.record_to_file('foo', :beep => nil, :maxduration => 2, :format => 'wav').should == :success_timeout
811
- end
816
+ end
812
817
 
813
818
  it 'set the format of a file via the :format option over-riding a implicit format' do
814
819
  mock_call.should_receive(:response).once.with("RECORD FILE", "foo.wav", "mpeg", "#", 2000, 0).and_return("200 result=0 (timeout) endpos=21600\n")
815
820
  mock_call.record_to_file('foo.wav', :beep => nil, :maxduration => 2, :format => 'mpeg').should == :success_timeout
816
- end
821
+ end
817
822
 
818
823
  it 'set the escapedigits if it is passed in' do
819
824
  mock_call.should_receive(:response).once.with("RECORD FILE", "foo", "gsm", "26", -1, 0).and_return("200 result=0 (timeout) endpos=21600\n")
820
825
  mock_call.record_to_file('foo', :beep => nil, :escapedigits => '26').should == :success_timeout
821
- end
826
+ end
822
827
 
823
828
  it 'play a passed in beep file if it is passed in' do
824
829
  mock_call.should_receive(:execute).once.with(:playback, 'my_awesome_beep.wav').and_return(true)
@@ -826,7 +831,7 @@ describe 'the #record_to_file method' do
826
831
  pbx_should_respond_with_playback_success
827
832
  mock_call.should_receive(:response).once.with("RECORD FILE", "foo", "gsm", "26", -1, 0).and_return("200 result=0 (timeout) endpos=21600\n")
828
833
  mock_call.record_to_file('foo', :beep => 'my_awesome_beep.wav', :escapedigits => '26').should == :success_timeout
829
- end
834
+ end
830
835
 
831
836
  it "should silently fail if the beep file passed in can't be played" do
832
837
  mock_call.should_receive(:execute).once.with(:playback, 'my_awesome_beep.wav').and_return(true)
@@ -834,12 +839,12 @@ describe 'the #record_to_file method' do
834
839
  pbx_should_respond_with_playback_failure
835
840
  mock_call.should_receive(:response).once.with("RECORD FILE", "foo", "gsm", "26", -1, 0).and_return("200 result=0 (timeout) endpos=21600\n")
836
841
  mock_call.record_to_file('foo', :beep => 'my_awesome_beep.wav', :escapedigits => '26').should == :success_timeout
837
- end
842
+ end
838
843
 
839
844
  it 'determine the format from the filename' do
840
845
  mock_call.should_receive(:response).once.with("RECORD FILE", "foo", "wav", "26", -1, 0).and_return("200 result=0 (timeout) endpos=21600\n")
841
846
  mock_call.record_to_file('foo.wav', :beep => nil, :escapedigits => '26').should == :success_timeout
842
- end
847
+ end
843
848
 
844
849
  it 'create a default filename if no file is specifed and icrement it on subsequent calls' do
845
850
  mock_call.should_receive(:new_guid).once.and_return('2345')
@@ -848,7 +853,7 @@ describe 'the #record_to_file method' do
848
853
  mock_call.should_receive(:response).once.with("RECORD FILE", "/tmp/recording_4322_1", "gsm", "26", -1, 0).and_return("200 result=0 (timeout) endpos=21600\n")
849
854
  mock_call.record_to_file(:beep => nil, :escapedigits => '26').should == :success_timeout
850
855
  mock_call.record_to_file(:beep => nil, :escapedigits => '26').should == :success_timeout
851
- end
856
+ end
852
857
  end
853
858
 
854
859
  describe 'The #record_to_file! method' do
@@ -862,19 +867,19 @@ describe 'The #record_to_file! method' do
862
867
  the_following_code {
863
868
  mock_call.record_to_file!('foo', :beep => 'my_awesome_beep.wav', :escapedigits => '26').should == :success_timeout
864
869
  }.should raise_error Adhearsion::VoIP::PlaybackError
865
- end
870
+ end
866
871
 
867
872
  it 'should throw RecordError if the recording had a problem writing the file' do
868
873
  mock_call.should_receive(:response).once.with("RECORD FILE", "foo", "gsm", "#", -1, 0, "BEEP").and_return("200 result=-1 (writefile) endpos=167840\n")
869
874
  the_following_code {
870
875
  mock_call.record_to_file!('foo').should == :write_error
871
876
  }.should raise_error Adhearsion::VoIP::RecordError
872
- end
877
+ end
873
878
 
874
879
  it 'should be able get a response from a successfull call' do
875
880
  mock_call.should_receive(:response).once.with("RECORD FILE", "foo", "wav", "26", -1, 0).and_return("200 result=0 (timeout) endpos=21600\n")
876
881
  mock_call.record_to_file!('foo.wav', :beep => nil, :escapedigits => '26').should == :success_timeout
877
- end
882
+ end
878
883
  end
879
884
 
880
885
  describe 'The #input method' do
@@ -1193,6 +1198,10 @@ describe 'The #input method' do
1193
1198
  pbx_was_asked_to_play files
1194
1199
  end
1195
1200
 
1201
+ it 'should raise ArgumentError if passed an empty :accept_key' do
1202
+ expect { mock_call.input 1, :accept_key => "" }.to raise_error ArgumentError
1203
+ end
1204
+
1196
1205
  end
1197
1206
 
1198
1207
  describe 'The #input! method' do
@@ -1389,6 +1398,10 @@ describe 'The #input! method' do
1389
1398
  pbx_was_asked_to_play played_files
1390
1399
  end
1391
1400
 
1401
+ it 'should raise ArgumentError if passed an empty :accept_key' do
1402
+ expect { mock_call.input 1, :accept_key => "" }.to raise_error ArgumentError
1403
+ end
1404
+
1392
1405
  end
1393
1406
 
1394
1407
  describe "The #variable method" do
@@ -64,6 +64,27 @@ describe "Using Invocations that've been ran through the Theatre" do
64
64
  invocation.error.should be_instance_of(ArgumentError)
65
65
  end
66
66
 
67
+ it "should trigger an exception event if an exception was raised" do
68
+ invocation = Theatre::Invocation.new("/namespace/whatever", lambda { raise ArgumentError, "this error is intentional" })
69
+ flexmock(Adhearsion::Events).should_receive(:trigger).once.with('/exception', FlexMock.any)
70
+ invocation.queued
71
+ invocation.start
72
+ end
73
+
74
+ it "should NOT trigger an exception if the exception occurs in an exception namespace" do
75
+ invocation = Theatre::Invocation.new("/exception", lambda { raise ArgumentError, "this error is intentional" })
76
+ flexmock(Adhearsion::Events).should_receive(:trigger).never
77
+ invocation.queued
78
+ invocation.start
79
+ end
80
+
81
+ it "should do the right thing with exceptions triggered with the wrong namespace" do
82
+ invocation = Theatre::Invocation.new(['exception'], lambda { raise ArgumentError, "this error is intentional" })
83
+ flexmock(Adhearsion::Events).should_receive(:trigger).never
84
+ invocation.queued
85
+ invocation.start
86
+ end
87
+
67
88
  it "should have a status of :success if no expection was raised" do
68
89
  callback = lambda { "No errors raised here!" }
69
90
  invocation = Theatre::Invocation.new("/namespace/whatever", callback)
@@ -69,6 +69,7 @@ describe "Theatre::Theatre" do
69
69
  theatre.register_callback_at_namespace "breakage", callback
70
70
  end
71
71
 
72
+ flexmock(Adhearsion::Events).should_receive(:trigger).once.with('/exception', FlexMock.on {|e| e.is_a?(StandardError)})
72
73
  return_value = theatre.trigger_immediately("breakage")
73
74
  return_value.first.should equal(1)
74
75
  return_value[1].should be_instance_of(LocalJumpError)
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: 1.2.4
4
+ version: 1.2.5
5
5
  prerelease:
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-01-26 00:00:00.000000000 Z
15
+ date: 2012-03-20 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: bundler
19
- requirement: &2152387620 !ruby/object:Gem::Requirement
19
+ requirement: &2164812460 !ruby/object:Gem::Requirement
20
20
  none: false
21
21
  requirements:
22
22
  - - ! '>='
@@ -24,10 +24,10 @@ dependencies:
24
24
  version: 1.0.10
25
25
  type: :runtime
26
26
  prerelease: false
27
- version_requirements: *2152387620
27
+ version_requirements: *2164812460
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: log4r
30
- requirement: &2152387100 !ruby/object:Gem::Requirement
30
+ requirement: &2164810380 !ruby/object:Gem::Requirement
31
31
  none: false
32
32
  requirements:
33
33
  - - ! '>='
@@ -35,10 +35,10 @@ dependencies:
35
35
  version: 1.0.5
36
36
  type: :runtime
37
37
  prerelease: false
38
- version_requirements: *2152387100
38
+ version_requirements: *2164810380
39
39
  - !ruby/object:Gem::Dependency
40
40
  name: activesupport
41
- requirement: &2152386600 !ruby/object:Gem::Requirement
41
+ requirement: &2164809260 !ruby/object:Gem::Requirement
42
42
  none: false
43
43
  requirements:
44
44
  - - ! '>='
@@ -46,10 +46,10 @@ dependencies:
46
46
  version: 2.1.0
47
47
  type: :runtime
48
48
  prerelease: false
49
- version_requirements: *2152386600
49
+ version_requirements: *2164809260
50
50
  - !ruby/object:Gem::Dependency
51
51
  name: i18n
52
- requirement: &2152386200 !ruby/object:Gem::Requirement
52
+ requirement: &2164808200 !ruby/object:Gem::Requirement
53
53
  none: false
54
54
  requirements:
55
55
  - - ! '>='
@@ -57,10 +57,10 @@ dependencies:
57
57
  version: '0'
58
58
  type: :runtime
59
59
  prerelease: false
60
- version_requirements: *2152386200
60
+ version_requirements: *2164808200
61
61
  - !ruby/object:Gem::Dependency
62
62
  name: json
63
- requirement: &2152385680 !ruby/object:Gem::Requirement
63
+ requirement: &2164806740 !ruby/object:Gem::Requirement
64
64
  none: false
65
65
  requirements:
66
66
  - - ! '>='
@@ -68,10 +68,10 @@ dependencies:
68
68
  version: '0'
69
69
  type: :runtime
70
70
  prerelease: false
71
- version_requirements: *2152385680
71
+ version_requirements: *2164806740
72
72
  - !ruby/object:Gem::Dependency
73
73
  name: thor
74
- requirement: &2152385260 !ruby/object:Gem::Requirement
74
+ requirement: &2164805980 !ruby/object:Gem::Requirement
75
75
  none: false
76
76
  requirements:
77
77
  - - ! '>='
@@ -79,10 +79,10 @@ dependencies:
79
79
  version: '0'
80
80
  type: :runtime
81
81
  prerelease: false
82
- version_requirements: *2152385260
82
+ version_requirements: *2164805980
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: rake
85
- requirement: &2152384840 !ruby/object:Gem::Requirement
85
+ requirement: &2164805280 !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: *2152384840
93
+ version_requirements: *2164805280
94
94
  - !ruby/object:Gem::Dependency
95
95
  name: pry
96
- requirement: &2152384380 !ruby/object:Gem::Requirement
96
+ requirement: &2164804440 !ruby/object:Gem::Requirement
97
97
  none: false
98
98
  requirements:
99
99
  - - ! '>='
@@ -101,21 +101,24 @@ dependencies:
101
101
  version: '0'
102
102
  type: :runtime
103
103
  prerelease: false
104
- version_requirements: *2152384380
104
+ version_requirements: *2164804440
105
105
  - !ruby/object:Gem::Dependency
106
106
  name: rspec
107
- requirement: &2152383840 !ruby/object:Gem::Requirement
107
+ requirement: &2164841480 !ruby/object:Gem::Requirement
108
108
  none: false
109
109
  requirements:
110
110
  - - ! '>='
111
111
  - !ruby/object:Gem::Version
112
112
  version: 2.4.0
113
+ - - <
114
+ - !ruby/object:Gem::Version
115
+ version: 2.8.0
113
116
  type: :development
114
117
  prerelease: false
115
- version_requirements: *2152383840
118
+ version_requirements: *2164841480
116
119
  - !ruby/object:Gem::Dependency
117
120
  name: flexmock
118
- requirement: &2152383380 !ruby/object:Gem::Requirement
121
+ requirement: &2164839340 !ruby/object:Gem::Requirement
119
122
  none: false
120
123
  requirements:
121
124
  - - ! '>='
@@ -123,10 +126,10 @@ dependencies:
123
126
  version: '0'
124
127
  type: :development
125
128
  prerelease: false
126
- version_requirements: *2152383380
129
+ version_requirements: *2164839340
127
130
  - !ruby/object:Gem::Dependency
128
131
  name: activerecord
129
- requirement: &2152382820 !ruby/object:Gem::Requirement
132
+ requirement: &2164837440 !ruby/object:Gem::Requirement
130
133
  none: false
131
134
  requirements:
132
135
  - - ! '>='
@@ -134,10 +137,10 @@ dependencies:
134
137
  version: 2.1.0
135
138
  type: :development
136
139
  prerelease: false
137
- version_requirements: *2152382820
140
+ version_requirements: *2164837440
138
141
  - !ruby/object:Gem::Dependency
139
142
  name: rake
140
- requirement: &2152382360 !ruby/object:Gem::Requirement
143
+ requirement: &2164848960 !ruby/object:Gem::Requirement
141
144
  none: false
142
145
  requirements:
143
146
  - - ! '>='
@@ -145,10 +148,10 @@ dependencies:
145
148
  version: '0'
146
149
  type: :development
147
150
  prerelease: false
148
- version_requirements: *2152382360
151
+ version_requirements: *2164848960
149
152
  - !ruby/object:Gem::Dependency
150
153
  name: simplecov
151
- requirement: &2152381860 !ruby/object:Gem::Requirement
154
+ requirement: &2164848040 !ruby/object:Gem::Requirement
152
155
  none: false
153
156
  requirements:
154
157
  - - ! '>='
@@ -156,10 +159,10 @@ dependencies:
156
159
  version: '0'
157
160
  type: :development
158
161
  prerelease: false
159
- version_requirements: *2152381860
162
+ version_requirements: *2164848040
160
163
  - !ruby/object:Gem::Dependency
161
164
  name: simplecov-rcov
162
- requirement: &2152381440 !ruby/object:Gem::Requirement
165
+ requirement: &2164846980 !ruby/object:Gem::Requirement
163
166
  none: false
164
167
  requirements:
165
168
  - - ! '>='
@@ -167,10 +170,10 @@ dependencies:
167
170
  version: '0'
168
171
  type: :development
169
172
  prerelease: false
170
- version_requirements: *2152381440
173
+ version_requirements: *2164846980
171
174
  - !ruby/object:Gem::Dependency
172
175
  name: ci_reporter
173
- requirement: &2152397320 !ruby/object:Gem::Requirement
176
+ requirement: &2164845760 !ruby/object:Gem::Requirement
174
177
  none: false
175
178
  requirements:
176
179
  - - ! '>='
@@ -178,7 +181,7 @@ dependencies:
178
181
  version: '0'
179
182
  type: :development
180
183
  prerelease: false
181
- version_requirements: *2152397320
184
+ version_requirements: *2164845760
182
185
  description: Adhearsion is an open-source telephony development framework
183
186
  email: dev&Adhearsion.com
184
187
  executables:
@@ -367,7 +370,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
367
370
  version: '0'
368
371
  segments:
369
372
  - 0
370
- hash: 2749044386952630171
373
+ hash: -4214800250478439630
371
374
  required_rubygems_version: !ruby/object:Gem::Requirement
372
375
  none: false
373
376
  requirements:
@@ -376,7 +379,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
376
379
  version: '0'
377
380
  segments:
378
381
  - 0
379
- hash: 2749044386952630171
382
+ hash: -4214800250478439630
380
383
  requirements: []
381
384
  rubyforge_project:
382
385
  rubygems_version: 1.8.10