sevenscale-adhearsion 0.7.1000

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.
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 +1186 -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 +402 -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 +453 -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
+ }