eric-adhearsion 0.7.999

Sign up to get free protection for your applications and to get access to all the features.
Files changed (150) hide show
  1. data/CHANGELOG +3 -0
  2. data/LICENSE +456 -0
  3. data/Manifest.txt +149 -0
  4. data/README.txt +6 -0
  5. data/Rakefile +48 -0
  6. data/ahn_generators/component/USAGE +5 -0
  7. data/ahn_generators/component/component_generator.rb +57 -0
  8. data/ahn_generators/component/templates/configuration.rb +0 -0
  9. data/ahn_generators/component/templates/lib/lib.rb.erb +3 -0
  10. data/ahn_generators/component/templates/test/test.rb.erb +12 -0
  11. data/ahn_generators/component/templates/test/test_helper.rb +14 -0
  12. data/app_generators/ahn/USAGE +5 -0
  13. data/app_generators/ahn/ahn_generator.rb +76 -0
  14. data/app_generators/ahn/templates/.ahnrc +12 -0
  15. data/app_generators/ahn/templates/README +8 -0
  16. data/app_generators/ahn/templates/Rakefile +3 -0
  17. data/app_generators/ahn/templates/components/simon_game/configuration.rb +0 -0
  18. data/app_generators/ahn/templates/components/simon_game/lib/simon_game.rb +61 -0
  19. data/app_generators/ahn/templates/components/simon_game/test/test_helper.rb +14 -0
  20. data/app_generators/ahn/templates/components/simon_game/test/test_simon_game.rb +31 -0
  21. data/app_generators/ahn/templates/config/startup.rb +53 -0
  22. data/app_generators/ahn/templates/dialplan.rb +4 -0
  23. data/bin/ahn +28 -0
  24. data/bin/ahnctl +68 -0
  25. data/bin/jahn +32 -0
  26. data/lib/adhearsion/blank_slate.rb +5 -0
  27. data/lib/adhearsion/cli.rb +106 -0
  28. data/lib/adhearsion/component_manager.rb +277 -0
  29. data/lib/adhearsion/core_extensions/all.rb +9 -0
  30. data/lib/adhearsion/core_extensions/array.rb +0 -0
  31. data/lib/adhearsion/core_extensions/custom_daemonizer.rb +45 -0
  32. data/lib/adhearsion/core_extensions/global.rb +1 -0
  33. data/lib/adhearsion/core_extensions/guid.rb +5 -0
  34. data/lib/adhearsion/core_extensions/hash.rb +0 -0
  35. data/lib/adhearsion/core_extensions/metaprogramming.rb +17 -0
  36. data/lib/adhearsion/core_extensions/numeric.rb +4 -0
  37. data/lib/adhearsion/core_extensions/proc.rb +0 -0
  38. data/lib/adhearsion/core_extensions/pseudo_uuid.rb +11 -0
  39. data/lib/adhearsion/core_extensions/publishable.rb +73 -0
  40. data/lib/adhearsion/core_extensions/relationship_properties.rb +40 -0
  41. data/lib/adhearsion/core_extensions/string.rb +26 -0
  42. data/lib/adhearsion/core_extensions/thread.rb +13 -0
  43. data/lib/adhearsion/core_extensions/thread_safety.rb +7 -0
  44. data/lib/adhearsion/core_extensions/time.rb +0 -0
  45. data/lib/adhearsion/distributed/gateways/dbus_gateway.rb +0 -0
  46. data/lib/adhearsion/distributed/gateways/osa_gateway.rb +0 -0
  47. data/lib/adhearsion/distributed/gateways/rest_gateway.rb +9 -0
  48. data/lib/adhearsion/distributed/gateways/soap_gateway.rb +9 -0
  49. data/lib/adhearsion/distributed/gateways/xmlrpc_gateway.rb +9 -0
  50. data/lib/adhearsion/distributed/peer_finder.rb +0 -0
  51. data/lib/adhearsion/distributed/remote_cli.rb +0 -0
  52. data/lib/adhearsion/hooks.rb +57 -0
  53. data/lib/adhearsion/host_definitions.rb +63 -0
  54. data/lib/adhearsion/initializer/asterisk.rb +59 -0
  55. data/lib/adhearsion/initializer/configuration.rb +202 -0
  56. data/lib/adhearsion/initializer/database.rb +92 -0
  57. data/lib/adhearsion/initializer/drb.rb +25 -0
  58. data/lib/adhearsion/initializer/freeswitch.rb +22 -0
  59. data/lib/adhearsion/initializer/paths.rb +55 -0
  60. data/lib/adhearsion/initializer/rails.rb +40 -0
  61. data/lib/adhearsion/initializer.rb +217 -0
  62. data/lib/adhearsion/logging.rb +92 -0
  63. data/lib/adhearsion/services/scheduler.rb +5 -0
  64. data/lib/adhearsion/tasks/database.rb +5 -0
  65. data/lib/adhearsion/tasks/generating.rb +20 -0
  66. data/lib/adhearsion/tasks/lint.rb +4 -0
  67. data/lib/adhearsion/tasks/testing.rb +37 -0
  68. data/lib/adhearsion/tasks.rb +15 -0
  69. data/lib/adhearsion/version.rb +9 -0
  70. data/lib/adhearsion/voip/asterisk/agi_server.rb +78 -0
  71. data/lib/adhearsion/voip/asterisk/ami/actions.rb +238 -0
  72. data/lib/adhearsion/voip/asterisk/ami/machine.rb +871 -0
  73. data/lib/adhearsion/voip/asterisk/ami/machine.rl +109 -0
  74. data/lib/adhearsion/voip/asterisk/ami/parser.rb +262 -0
  75. data/lib/adhearsion/voip/asterisk/ami.rb +147 -0
  76. data/lib/adhearsion/voip/asterisk/commands.rb +1182 -0
  77. data/lib/adhearsion/voip/asterisk/config_generators/agents.conf.rb +140 -0
  78. data/lib/adhearsion/voip/asterisk/config_generators/config_generator.rb +101 -0
  79. data/lib/adhearsion/voip/asterisk/config_generators/queues.conf.rb +250 -0
  80. data/lib/adhearsion/voip/asterisk/config_generators/voicemail.conf.rb +240 -0
  81. data/lib/adhearsion/voip/asterisk/config_manager.rb +71 -0
  82. data/lib/adhearsion/voip/asterisk/special_dial_plan_managers.rb +80 -0
  83. data/lib/adhearsion/voip/asterisk.rb +4 -0
  84. data/lib/adhearsion/voip/call.rb +391 -0
  85. data/lib/adhearsion/voip/call_routing.rb +64 -0
  86. data/lib/adhearsion/voip/commands.rb +9 -0
  87. data/lib/adhearsion/voip/constants.rb +39 -0
  88. data/lib/adhearsion/voip/conveniences.rb +18 -0
  89. data/lib/adhearsion/voip/dial_plan.rb +205 -0
  90. data/lib/adhearsion/voip/dsl/dialing_dsl/dialing_dsl_monkey_patches.rb +37 -0
  91. data/lib/adhearsion/voip/dsl/dialing_dsl.rb +151 -0
  92. data/lib/adhearsion/voip/dsl/dialplan/control_passing_exception.rb +27 -0
  93. data/lib/adhearsion/voip/dsl/dialplan/dispatcher.rb +124 -0
  94. data/lib/adhearsion/voip/dsl/dialplan/parser.rb +75 -0
  95. data/lib/adhearsion/voip/dsl/dialplan/thread_mixin.rb +16 -0
  96. data/lib/adhearsion/voip/dsl/numerical_string.rb +117 -0
  97. data/lib/adhearsion/voip/freeswitch/basic_connection_manager.rb +48 -0
  98. data/lib/adhearsion/voip/freeswitch/event_handler.rb +58 -0
  99. data/lib/adhearsion/voip/freeswitch/freeswitch_dialplan_command_factory.rb +129 -0
  100. data/lib/adhearsion/voip/freeswitch/inbound_connection_manager.rb +38 -0
  101. data/lib/adhearsion/voip/freeswitch/oes_server.rb +195 -0
  102. data/lib/adhearsion/voip/menu_state_machine/calculated_match.rb +80 -0
  103. data/lib/adhearsion/voip/menu_state_machine/matchers.rb +123 -0
  104. data/lib/adhearsion/voip/menu_state_machine/menu_builder.rb +58 -0
  105. data/lib/adhearsion/voip/menu_state_machine/menu_class.rb +149 -0
  106. data/lib/adhearsion.rb +31 -0
  107. data/script/destroy +14 -0
  108. data/script/generate +14 -0
  109. data/spec/fixtures/dialplan.rb +3 -0
  110. data/spec/initializer/test_configuration.rb +267 -0
  111. data/spec/initializer/test_loading.rb +162 -0
  112. data/spec/initializer/test_paths.rb +43 -0
  113. data/spec/silence.rb +10 -0
  114. data/spec/test_ahn_command.rb +149 -0
  115. data/spec/test_code_quality.rb +87 -0
  116. data/spec/test_component_manager.rb +97 -0
  117. data/spec/test_constants.rb +8 -0
  118. data/spec/test_drb.rb +104 -0
  119. data/spec/test_helper.rb +94 -0
  120. data/spec/test_hooks.rb +37 -0
  121. data/spec/test_host_definitions.rb +79 -0
  122. data/spec/test_initialization.rb +105 -0
  123. data/spec/test_logging.rb +80 -0
  124. data/spec/test_relationship_properties.rb +54 -0
  125. data/spec/voip/asterisk/ami_response_definitions.rb +23 -0
  126. data/spec/voip/asterisk/config_file_generators/test_agents.rb +253 -0
  127. data/spec/voip/asterisk/config_file_generators/test_queues.rb +325 -0
  128. data/spec/voip/asterisk/config_file_generators/test_voicemail.rb +306 -0
  129. data/spec/voip/asterisk/menu_command/test_calculated_match.rb +111 -0
  130. data/spec/voip/asterisk/menu_command/test_matchers.rb +98 -0
  131. data/spec/voip/asterisk/mock_ami_server.rb +176 -0
  132. data/spec/voip/asterisk/test_agi_server.rb +451 -0
  133. data/spec/voip/asterisk/test_ami.rb +227 -0
  134. data/spec/voip/asterisk/test_commands.rb +2006 -0
  135. data/spec/voip/asterisk/test_config_manager.rb +129 -0
  136. data/spec/voip/dsl/dispatcher_spec_helper.rb +45 -0
  137. data/spec/voip/dsl/test_dialing_dsl.rb +268 -0
  138. data/spec/voip/dsl/test_dispatcher.rb +82 -0
  139. data/spec/voip/dsl/test_parser.rb +87 -0
  140. data/spec/voip/freeswitch/test_basic_connection_manager.rb +39 -0
  141. data/spec/voip/freeswitch/test_inbound_connection_manager.rb +39 -0
  142. data/spec/voip/freeswitch/test_oes_server.rb +9 -0
  143. data/spec/voip/test_call_routing.rb +127 -0
  144. data/spec/voip/test_dialplan_manager.rb +372 -0
  145. data/spec/voip/test_numerical_string.rb +48 -0
  146. data/spec/voip/test_phone_number.rb +36 -0
  147. data/test/test_ahn_generator.rb +59 -0
  148. data/test/test_component_generator.rb +52 -0
  149. data/test/test_generator_helper.rb +20 -0
  150. metadata +254 -0
@@ -0,0 +1,123 @@
1
+ require File.join(File.dirname(__FILE__), 'calculated_match')
2
+
3
+ module Adhearsion
4
+ module VoIP
5
+ class MatchCalculator
6
+
7
+ class << self
8
+
9
+ def build_with_pattern(pattern, match_payload, &block)
10
+ class_for_pattern_type(pattern.class.name).new(pattern, match_payload, &block)
11
+ end
12
+
13
+ def inherited(klass)
14
+ subclasses << klass
15
+ end
16
+
17
+ private
18
+
19
+ def class_for_pattern_type(pattern_type)
20
+ sought_class_name = "Adhearsion::VoIP::#{pattern_type.camelize}MatchCalculator"
21
+ subclasses.find { |klass| klass.name == sought_class_name }
22
+ end
23
+
24
+ def subclasses
25
+ @@subclasses ||= []
26
+ end
27
+
28
+ end
29
+
30
+ attr_reader :pattern, :match_payload
31
+ def initialize(pattern, match_payload)
32
+ @pattern, @match_payload = pattern, match_payload
33
+ end
34
+
35
+ protected
36
+
37
+ def new_calculated_match(options)
38
+ CalculatedMatch.new({:pattern => pattern, :match_payload => match_payload}.merge(options))
39
+ end
40
+
41
+ def coerce_to_numeric(victim)
42
+ victim.kind_of?(Numeric) ? victim : (victim.to_s =~ /^\d+$/ ? victim.to_s.to_i : nil )
43
+ end
44
+ end
45
+
46
+ class RangeMatchCalculator < MatchCalculator
47
+
48
+ def initialize(pattern, match_payload)
49
+ raise unless pattern.first.kind_of?(Numeric) && pattern.last.kind_of?(Numeric)
50
+ super
51
+ end
52
+
53
+ def match(query)
54
+ numerical_query = coerce_to_numeric query
55
+ if numerical_query
56
+ exact_match = pattern.include?(numerical_query) ? query : nil
57
+ potential_matches = numbers_in_range_like numerical_query
58
+ potential_matches.reject! { |m| m.to_s == exact_match.to_s } if exact_match
59
+
60
+ new_calculated_match :query => query, :exact_matches => exact_match,
61
+ :potential_matches => potential_matches
62
+ else
63
+ CalculatedMatch.failed_match!(pattern, query, match_payload)
64
+ end
65
+ end
66
+
67
+ private
68
+
69
+ # Returns all numbers in the range (@pattern) that +begin with+ the number given
70
+ # as the first argument.
71
+ #
72
+ # NOTE! If you're having trouble reading what this method is actually doing, it's
73
+ # effectively a much more efficient version of this:
74
+ #
75
+ # pattern.to_a.select { |x| x.to_s.starts_with? num.to_s }.flatten
76
+ #
77
+ # Huge thanks to Dave Troy (http://davetroy.blogspot.com) for this awesomely
78
+ # efficient code!
79
+ def numbers_in_range_like(num)
80
+ return (pattern === 0 ? [0] : nil) if num == 0
81
+ raise ArgumentError unless num.kind_of?(Numeric)
82
+ returning Array.new do |matches|
83
+ first, last = pattern.first, pattern.last
84
+ power = 0
85
+ while num < last
86
+ ones_count = 10**power - 1
87
+ matches.concat((([num, first].max)..[(num+ones_count), last].min).to_a)
88
+ num *= 10
89
+ power += 1
90
+ end
91
+ end
92
+ end
93
+ end
94
+
95
+ class FixnumMatchCalculator < MatchCalculator
96
+ def match(query)
97
+ numeric_query = coerce_to_numeric query
98
+ exact_match, potential_match = nil
99
+ if pattern == numeric_query
100
+ exact_match = pattern
101
+ elsif pattern.to_s.starts_with? query.to_s
102
+ potential_match = pattern
103
+ end
104
+ new_calculated_match :query => query, :exact_matches => exact_match, :potential_matches => potential_match
105
+ end
106
+ end
107
+
108
+ class StringMatchCalculator < MatchCalculator
109
+ def match(query)
110
+ args = { :query => query, :exact_matches => nil,
111
+ :potential_matches => nil }
112
+
113
+ if pattern == query.to_s
114
+ args[:exact_matches] = [pattern]
115
+ elsif pattern.starts_with? query.to_s
116
+ args[:potential_matches] = [pattern]
117
+ end
118
+
119
+ new_calculated_match args
120
+ end
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,58 @@
1
+ require File.join(File.dirname(__FILE__), 'matchers.rb')
2
+
3
+ module Adhearsion
4
+ module VoIP
5
+ class MenuBuilder
6
+
7
+ def initialize
8
+ @patterns = []
9
+ @menu_callbacks = {}
10
+ end
11
+
12
+ def method_missing(match_payload, *patterns, &block)
13
+ name_string = match_payload.to_s
14
+ if patterns.any?
15
+ patterns.each do |pattern|
16
+ @patterns << MatchCalculator.build_with_pattern(pattern, match_payload)
17
+ end
18
+ else
19
+ raise ArgumentError, "You cannot call this method without patterns!"
20
+ end
21
+ nil
22
+ end
23
+
24
+ def weighted_match_calculators
25
+ @patterns
26
+ end
27
+
28
+ def execute_hook_for(symbol, input)
29
+ callback = @menu_callbacks[symbol]
30
+ callback.call input if callback
31
+ end
32
+
33
+ def on_invalid(&block)
34
+ raise LocalJumpError, "Must supply a block!" unless block_given?
35
+ @menu_callbacks[:invalid] = block
36
+ end
37
+
38
+ def on_premature_timeout(&block)
39
+ raise LocalJumpError, "Must supply a block!" unless block_given?
40
+ @menu_callbacks[:premature_timeout] = block
41
+ end
42
+
43
+ def on_failure(&block)
44
+ raise LocalJumpError, "Must supply a block!" unless block_given?
45
+ @menu_callbacks[:failure] = block
46
+ end
47
+
48
+ def calculate_matches_for(result)
49
+ returning CalculatedMatchCollection.new do |collection|
50
+ weighted_match_calculators.each do |pattern|
51
+ collection << pattern.match(result)
52
+ end
53
+ end
54
+ end
55
+
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,149 @@
1
+ require 'adhearsion/voip/menu_state_machine/menu_builder'
2
+ module Adhearsion
3
+ module VoIP
4
+ class Menu
5
+
6
+ DEFAULT_MAX_NUMBER_OF_TRIES = 1
7
+ DEFAULT_TIMEOUT = 5 # seconds
8
+
9
+ relationships :menu_builder => MenuBuilder
10
+
11
+ attr_reader :builder, :timeout, :tries_count, :max_number_of_tries
12
+ def initialize(options={}, &block)
13
+ @tries_count = 0 # Counts the number of tries the menu's been executed
14
+
15
+ @timeout = options[:timeout] || DEFAULT_TIMEOUT
16
+ @max_number_of_tries = options[:tries] || DEFAULT_MAX_NUMBER_OF_TRIES
17
+
18
+ @builder = menu_builder.new
19
+ yield @builder
20
+
21
+ initialize_digit_buffer
22
+ end
23
+
24
+ def <<(other)
25
+ digit_buffer << other
26
+ end
27
+
28
+ def digit_buffer
29
+ @digit_buffer
30
+ end
31
+
32
+ def digit_buffer_string
33
+ digit_buffer.to_s
34
+ end
35
+
36
+ def digit_buffer_empty?
37
+ digit_buffer.empty?
38
+ end
39
+
40
+ def continue
41
+ raise MenuGetAnotherDigitOrTimeout if digit_buffer_empty?
42
+
43
+ calculated_matches = builder.calculate_matches_for digit_buffer_string
44
+
45
+ if calculated_matches.exact_match_count >= 1
46
+ first_exact_match = calculated_matches.exact_matches.first
47
+ if calculated_matches.potential_match_count.zero?
48
+ # Match found with no extenuating ambiguities! Go with the first exact match
49
+ menu_result_found! first_exact_match.match_payload, digit_buffer_string
50
+ else
51
+ get_another_digit_or_finish!(first_exact_match.match_payload, first_exact_match.query)
52
+ end
53
+ elsif calculated_matches.potential_match_count >= 1
54
+ get_another_digit_or_timeout!
55
+ else
56
+ invalid!
57
+ end
58
+ end
59
+
60
+ def should_continue?
61
+ tries_count < max_number_of_tries
62
+ end
63
+
64
+ def restart!
65
+ @tries_count += 1
66
+ digit_buffer.clear!
67
+ end
68
+
69
+ def execute_invalid_hook
70
+ builder.execute_hook_for(:invalid, digit_buffer_string)
71
+ end
72
+
73
+ def execute_timeout_hook
74
+ builder.execute_hook_for(:premature_timeout, digit_buffer_string)
75
+ end
76
+
77
+ def execute_failure_hook
78
+ builder.execute_hook_for(:failure, digit_buffer_string)
79
+ end
80
+
81
+ protected
82
+
83
+ # If you're using a more complex class in subclasses, you may want to override this method in addition to the
84
+ # digit_buffer, digit_buffer_empty, and digit_buffer_string methods
85
+ def initialize_digit_buffer
86
+ @digit_buffer = ClearableStringBuffer.new
87
+ end
88
+
89
+ def invalid!
90
+ raise MenuResultInvalid
91
+ end
92
+
93
+ def menu_result_found!(match_payload, new_extension)
94
+ raise MenuResultFound.new(match_payload, new_extension)
95
+ end
96
+
97
+ def get_another_digit_or_finish!(match_payload, new_extension)
98
+ raise MenuGetAnotherDigitOrFinish.new(match_payload, new_extension)
99
+ end
100
+
101
+ def get_another_digit_or_timeout!
102
+ raise MenuGetAnotherDigitOrTimeout
103
+ end
104
+
105
+ # The superclass from which all message-like exceptions decend. It should never
106
+ # be instantiated directly.
107
+ class MenuResult < Exception; end
108
+
109
+ # Raised when the user's input matches
110
+ class MenuResultFound < MenuResult
111
+ attr_reader :match_payload, :new_extension
112
+ def initialize(match_payload, new_extension)
113
+ super()
114
+ @match_payload = match_payload
115
+ @new_extension = new_extension
116
+ end
117
+ end
118
+
119
+ module MenuGetAnotherDigit; end
120
+
121
+ class MenuGetAnotherDigitOrFinish < MenuResultFound
122
+ include MenuGetAnotherDigit
123
+ end
124
+
125
+ class MenuGetAnotherDigitOrTimeout < MenuResult
126
+ include MenuGetAnotherDigit
127
+ end
128
+
129
+ class MenuResultFound < MenuResult; end
130
+
131
+ # Raised when the user's input matches no patterns
132
+ class MenuResultInvalid < MenuResult; end
133
+
134
+ # For our default purposes, we need the digit_buffer to behave much like a normal String except that it should
135
+ # handle its own resetting (clearing).
136
+ class ClearableStringBuffer < String
137
+ def clear!
138
+ replace ""
139
+ end
140
+
141
+ def <<(other)
142
+ super other.to_s
143
+ end
144
+
145
+ end
146
+
147
+ end
148
+ end
149
+ end
data/lib/adhearsion.rb ADDED
@@ -0,0 +1,31 @@
1
+ # Check the Ruby version
2
+ STDERR.puts "WARNING: You are running Adhearsion in an unsupported
3
+ version of Ruby (Ruby #{RUBY_VERSION} #{RUBY_RELEASE_DATE})!
4
+ Please upgrade to at least Ruby v1.8.5." if RUBY_VERSION < "1.8.5"
5
+
6
+ module Adhearsion
7
+ # Sets up the Gem require path.
8
+ AHN_INSTALL_DIR = File.expand_path(File.dirname(__FILE__) + "/..")
9
+ CONFIG = {}
10
+ end
11
+
12
+ $: << File.expand_path(File.dirname(__FILE__))
13
+
14
+ require 'rubygems'
15
+ require 'adhearsion/version'
16
+ require 'adhearsion/voip/call'
17
+ require 'adhearsion/voip/dial_plan'
18
+ require 'adhearsion/voip/asterisk/special_dial_plan_managers'
19
+ require 'adhearsion/core_extensions/all'
20
+ require 'adhearsion/blank_slate'
21
+ require 'adhearsion/hooks'
22
+ require 'adhearsion/logging'
23
+ require 'adhearsion/initializer/configuration'
24
+ require 'adhearsion/initializer'
25
+ require 'adhearsion/initializer/paths'
26
+ require 'adhearsion/voip/dsl/numerical_string'
27
+ require 'adhearsion/voip/dsl/dialplan/parser'
28
+ require 'adhearsion/voip/commands'
29
+ require 'adhearsion/voip/asterisk/commands'
30
+ require 'adhearsion/voip/dsl/dialing_dsl'
31
+ require 'adhearsion/voip/call_routing'
data/script/destroy ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.join(File.dirname(__FILE__), '..')
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/destroy'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, "test_unit"]
14
+ RubiGen::Scripts::Destroy.new.run(ARGV)
data/script/generate ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.join(File.dirname(__FILE__), '..')
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/generate'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, "test_unit"]
14
+ RubiGen::Scripts::Generate.new.run(ARGV)
@@ -0,0 +1,3 @@
1
+ sample_context {
2
+ raise 'the body of this context should not have been evaluated'
3
+ }
@@ -0,0 +1,267 @@
1
+ require File.dirname(__FILE__) + "/../test_helper"
2
+
3
+ context "Configuration defaults" do
4
+ include ConfigurationTestHelper
5
+ attr_reader :config
6
+
7
+ setup do
8
+ @config = default_config
9
+ end
10
+
11
+ test "incoming calls are answered by default" do
12
+ assert config.automatically_answer_incoming_calls
13
+ end
14
+
15
+ test "calls are ended when hung up" do
16
+ assert config.end_call_on_hangup
17
+ end
18
+
19
+ test "if an error occurs, a call is hungup" do
20
+ assert config.end_call_on_error
21
+ end
22
+
23
+ test "asterisk is enabled by default" do
24
+ assert config.asterisk_enabled?
25
+ end
26
+
27
+ test "default asterisk configuration is available" do
28
+ assert_kind_of Adhearsion::Configuration::AsteriskConfiguration, config.asterisk
29
+ end
30
+
31
+ test "database access is NOT enabled by default" do
32
+ assert !config.database_enabled?
33
+ end
34
+
35
+ test "freeswith is NOT enabled by default" do
36
+ assert !config.freeswitch_enabled?
37
+ end
38
+
39
+ test "AMI is NOT enabled by default" do
40
+ assert !config.asterisk.ami_enabled?
41
+ end
42
+
43
+ test "Drb is NOT enabled by default" do
44
+ assert !config.drb_enabled?
45
+ end
46
+ end
47
+
48
+ context "Asterisk AGI configuration defaults" do
49
+ attr_reader :config
50
+
51
+ setup do
52
+ @config = Adhearsion::Configuration::AsteriskConfiguration.new
53
+ end
54
+
55
+ test "asterisk configuration sets default listening port" do
56
+ config.listening_port.should.equal Adhearsion::Configuration::AsteriskConfiguration.default_listening_port
57
+ end
58
+
59
+ test "asterisk configuration sets default listening host" do
60
+ config.listening_host.should.equal Adhearsion::Configuration::AsteriskConfiguration.default_listening_host
61
+ end
62
+ end
63
+
64
+ context 'Logging configuration' do
65
+
66
+ attr_reader :config
67
+ before :each do
68
+ @config = Adhearsion::Configuration.new
69
+ end
70
+
71
+ after :each do
72
+ Adhearsion::Logging.logging_level = :fatal
73
+ end
74
+
75
+ test 'the logging level should translate from symbols into Log4r constants' do
76
+ Adhearsion::Logging.logging_level.should.not.equal Log4r::WARN
77
+ config.logging :level => :warn
78
+ Adhearsion::Logging.logging_level.should.equal Log4r::WARN
79
+ end
80
+
81
+ end
82
+
83
+ context "AMI configuration defaults" do
84
+ attr_reader :config
85
+
86
+ setup do
87
+ @config = Adhearsion::Configuration::AsteriskConfiguration::AMIConfiguration.new
88
+ end
89
+
90
+ test "ami configuration sets default port" do
91
+ config.port.should.equal Adhearsion::Configuration::AsteriskConfiguration::AMIConfiguration.default_port
92
+ end
93
+
94
+ test "ami allows you to configure a username and a password, both of which default to nil" do
95
+ config.username.should.be.nil
96
+ config.password.should.be.nil
97
+ end
98
+ end
99
+
100
+ context "Rails configuration defaults" do
101
+ test "should require the path to the Rails app in the constructor" do
102
+ config = Adhearsion::Configuration::RailsConfiguration.new :path => "path here doesn't matter right now", :env => :development
103
+ config.rails_root.should.not.be.nil
104
+ end
105
+
106
+ test "should expand_path() the first constructor parameter" do
107
+ rails_root = "gui"
108
+ flexmock(File).should_receive(:expand_path).once.with(rails_root)
109
+ config = Adhearsion::Configuration::RailsConfiguration.new :path => rails_root, :env => :development
110
+ end
111
+
112
+ test "should ensure that the environment provided is one supported by Rails" do
113
+ the_following_code {
114
+ Adhearsion::Configuration::RailsConfiguration.new :path => "doesnt matter", :env => :this_is_not_a_rails_env
115
+ }.should.raise ArgumentError
116
+
117
+ the_following_code {
118
+ Adhearsion::Configuration::RailsConfiguration.new :path => "doesnt matter", :env => :development
119
+ Adhearsion::Configuration::RailsConfiguration.new :path => "doesnt matter", :env => :production
120
+ Adhearsion::Configuration::RailsConfiguration.new :path => "doesnt matter", :env => :test
121
+ }.should.not.raise ArgumentError
122
+ end
123
+
124
+ test "should convert the environment into a Symbol" do
125
+ Adhearsion::Configuration::RailsConfiguration::SUPPORTED_RAILS_ENVIRONMENTS.should.not.be.empty
126
+ Adhearsion::Configuration::RailsConfiguration::SUPPORTED_RAILS_ENVIRONMENTS.each do |env|
127
+ config = Adhearsion::Configuration::RailsConfiguration.new :path => "doesnt matter", :env => env.to_s
128
+ config.environment.should.equal env
129
+ end
130
+ end
131
+ end
132
+
133
+ context "Database configuration defaults" do
134
+
135
+ setup do
136
+ Adhearsion.send(:remove_const, :AHN_CONFIG) if Adhearsion.const_defined?(:AHN_CONFIG)
137
+ Adhearsion::Configuration.configure {}
138
+ end
139
+
140
+ it "should store the constructor's argument in connection_options()" do
141
+ sample_options = { :adapter => "sqlite3", :dbfile => "foo.sqlite3" }
142
+ config = Adhearsion::Configuration::DatabaseConfiguration.new(sample_options)
143
+ config.connection_options.should.equal sample_options
144
+ end
145
+ it "should remove the :orm key from the connection options" do
146
+ sample_options = { :orm => :active_record, :adapter => "mysql", :host => "::1",
147
+ :user => "a", :pass => "b", :database => "ahn" }
148
+ config = Adhearsion::Configuration::DatabaseConfiguration.new(sample_options.clone)
149
+ config.orm.should.equal sample_options.delete(:orm)
150
+ config.connection_options.should.equal sample_options
151
+ end
152
+ end
153
+
154
+ context "Freeswitch configuration defaults" do
155
+ attr_reader :config
156
+
157
+ setup do
158
+ @config = Adhearsion::Configuration::FreeswitchConfiguration.new
159
+ end
160
+
161
+ test "freeswitch configuration sets default listening port" do
162
+ config.listening_port.should.equal Adhearsion::Configuration::FreeswitchConfiguration.default_listening_port
163
+ end
164
+
165
+ test "freeswitch configuration sets default listening host" do
166
+ config.listening_host.should.equal Adhearsion::Configuration::FreeswitchConfiguration.default_listening_host
167
+ end
168
+ end
169
+
170
+ context "Configuration scenarios" do
171
+ include ConfigurationTestHelper
172
+
173
+ test "enabling AMI using all its defaults" do
174
+ config = enable_ami
175
+
176
+ assert config.asterisk.ami_enabled?
177
+ config.asterisk.ami.should.be.kind_of Adhearsion::Configuration::AsteriskConfiguration::AMIConfiguration
178
+ end
179
+
180
+ test "enabling AMI with custom configuration overrides the defaults" do
181
+ overridden_port = 911
182
+ config = enable_ami :port => overridden_port
183
+ config.asterisk.ami.port.should.equal overridden_port
184
+ end
185
+
186
+ test "enabling Drb without any configuration" do
187
+ config = enable_drb
188
+ assert config.drb
189
+ config.drb.should.be.kind_of Adhearsion::Configuration::DrbConfiguration
190
+ end
191
+
192
+ test "enabling Drb with a port specified sets the port" do
193
+ target_port = 911
194
+ config = enable_drb :port => target_port
195
+ config.drb.port.should.be.equal target_port
196
+ end
197
+
198
+ private
199
+ def enable_ami(*overrides)
200
+ default_config do |config|
201
+ config.asterisk.enable_ami(*overrides)
202
+ end
203
+ end
204
+
205
+ def enable_drb(*overrides)
206
+ default_config do |config|
207
+ config.enable_drb *overrides
208
+ end
209
+ end
210
+ end
211
+
212
+ context "AHN_CONFIG" do
213
+ setup do
214
+ Adhearsion.send(:remove_const, :AHN_CONFIG) if Adhearsion.const_defined?(:AHN_CONFIG)
215
+ end
216
+
217
+ test "Running configure sets configuration to Adhearsion::AHN_CONFIG" do
218
+ assert !Adhearsion.const_defined?(:AHN_CONFIG)
219
+ Adhearsion::Configuration.configure do |config|
220
+ # Nothing needs to happen here
221
+ end
222
+
223
+ assert Adhearsion.const_defined?(:AHN_CONFIG)
224
+ Adhearsion::AHN_CONFIG.should.be.kind_of(Adhearsion::Configuration)
225
+ end
226
+ end
227
+
228
+ context "DRb configuration" do
229
+ test "should not add any ACL rules when :raw_acl is passed in" do
230
+ config = Adhearsion::Configuration::DrbConfiguration.new :raw_acl => :this_is_an_acl
231
+ config.acl.should.equal :this_is_an_acl
232
+ end
233
+
234
+ test "should, by default, allow only localhost connections" do
235
+ config = Adhearsion::Configuration::DrbConfiguration.new
236
+ config.acl.should == %w[allow 127.0.0.1]
237
+ end
238
+
239
+ test "should add ACL 'deny' rules before 'allow' rules" do
240
+ config = Adhearsion::Configuration::DrbConfiguration.new :allow => %w[1.1.1.1 2.2.2.2],
241
+ :deny => %w[9.9.9.9]
242
+ config.acl.should == %w[deny 9.9.9.9 allow 1.1.1.1 allow 2.2.2.2]
243
+ end
244
+
245
+ test "should allow both an Array and a String to be passed as an allow/deny ACL rule" do
246
+ config = Adhearsion::Configuration::DrbConfiguration.new :allow => "1.1.1.1", :deny => "9.9.9.9"
247
+ config.acl.should == %w[deny 9.9.9.9 allow 1.1.1.1]
248
+ end
249
+
250
+ test "should have a default host and port" do
251
+ config = Adhearsion::Configuration::DrbConfiguration.new
252
+ config.host.should.not.equal nil
253
+ config.port.should.not.equal nil
254
+ end
255
+
256
+ end
257
+
258
+ BEGIN {
259
+ module ConfigurationTestHelper
260
+ def default_config(&block)
261
+ Adhearsion::Configuration.new do |config|
262
+ config.enable_asterisk
263
+ yield config if block_given?
264
+ end
265
+ end
266
+ end
267
+ }