adhearsion 1.2.4 → 1.2.5

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 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