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,162 @@
1
+ require File.dirname(__FILE__) + "/../test_helper"
2
+ require 'adhearsion/initializer/database'
3
+ require 'adhearsion/initializer/asterisk'
4
+ require 'adhearsion/initializer/rails'
5
+ require 'active_record'
6
+
7
+ context "The database initializer" do
8
+
9
+ include DatabaseInitializationTestHelper
10
+
11
+ test "starts a connection through ActiveRecord" do
12
+ connection_options = { :adapter => "sqlite3",
13
+ :dbfile => "foo.sqlite3" }
14
+ flexmock(Adhearsion::Initializer::DatabaseInitializer).should_receive(:require_models).once
15
+ flexmock(ActiveRecord::Base).should_receive(:establish_connection).with(connection_options)
16
+
17
+ start_database_initializer_with_options connection_options
18
+ end
19
+
20
+ test "should make any required models available in the main namespace" do
21
+ bogus_model = tempfile_with_contents sample_user_model
22
+ flexmock(Adhearsion::Initializer::DatabaseInitializer).should_receive(:all_models).and_return([bogus_model.path])
23
+ start_database_initializer
24
+ User.superclass.should.equal ActiveRecord::Base
25
+ end
26
+
27
+ test 'should enable ActiveRecord concurrency' do
28
+ bogus_model = tempfile_with_contents sample_user_model
29
+ flexmock(Adhearsion::Initializer::DatabaseInitializer).should_receive(:all_models).and_return([bogus_model.path])
30
+ start_database_initializer
31
+ ActiveRecord::Base.send(:class_variable_get, :@@allow_concurrency).should.be true
32
+ end
33
+
34
+ end
35
+
36
+ context "The Asterisk initializer" do
37
+
38
+ include AsteriskInitializerTestHelper
39
+
40
+ test "starts the AGI server" do
41
+ initialize_asterisk_with_defaults
42
+ flexmock(Adhearsion::VoIP::Asterisk::AGI::Server).new_instances.should_receive(:start).once
43
+ end
44
+
45
+ test "starts the AGI server with any overridden settings" do
46
+ overrides = {:host => "127.0.0.1", :port => 7788}
47
+ config_overrides = {:listening_host => overrides[:host], :listening_port => overrides[:port]}
48
+ initialize_asterisk_with_options config_overrides
49
+ flexmock(Adhearsion::VoIP::Asterisk::AGI::Server).new_instances.should_receive(:start).once.with(overrides)
50
+ end
51
+
52
+ end
53
+
54
+ context "The Rails initializer" do
55
+
56
+ include RailsInitializerTestHelper
57
+
58
+ test "should load the config/environment.rb file within the rails_root path" do
59
+ rails_root = "/path/to/rails/app"
60
+ environment_rb = rails_root + '/config/environment.rb'
61
+ flexmock(Adhearsion::Initializer::RailsInitializer).should_receive(:require).once.with environment_rb
62
+ stub_file_checking_methods!
63
+ stub_before_call_hook!
64
+ initialize_rails_with_options :rails_root => rails_root, :environment => :development
65
+ end
66
+
67
+ test "should raise an exception if the database is initialized at the same time" do
68
+ flexmock(Adhearsion::AHN_CONFIG).should_receive(:database_enabled?).and_return true
69
+ flexmock(Adhearsion::Initializer::RailsInitializer).should_receive(:require).and_return
70
+ stub_file_checking_methods!
71
+ stub_before_call_hook!
72
+ the_following_code {
73
+ initialize_rails_with_options :rails_root => '/tmp', :environment => :development
74
+ }.should.raise
75
+ end
76
+
77
+ test "should set the RAILS_ENV to be the argument passed in" do
78
+ flexmock(ENV).should_receive(:[]=).once.with("RAILS_ENV", "development")
79
+ flexmock(Adhearsion::Initializer::RailsInitializer).should_receive(:require).once.and_return
80
+ stub_file_checking_methods!
81
+ stub_before_call_hook!
82
+ initialize_rails_with_options :rails_root => '/tmp', :environment => :development
83
+ end
84
+
85
+ test 'should enable ActiveRecord concurrency' do
86
+ flexstub(Adhearsion::Initializer::RailsInitializer).should_receive :require
87
+ flexstub(Adhearsion::Initializer::RailsInitializer).should_receive :load_rails
88
+ stub_file_checking_methods!
89
+ stub_before_call_hook!
90
+ initialize_rails_with_options :rails_root => '/path/somewhere', :environment => :development
91
+ ActiveRecord::Base.send(:class_variable_get, :@@allow_concurrency).should.equal true
92
+ end
93
+
94
+ test 'should create a BeforeCall hook (presumably to verify the active connections)' do
95
+ flexstub(Adhearsion::Initializer::RailsInitializer).should_receive :require
96
+ flexstub(Adhearsion::Initializer::RailsInitializer).should_receive :load_rails
97
+ stub_file_checking_methods!
98
+ flexmock(Adhearsion::Hooks::BeforeCall).should_receive(:create_hook).once
99
+ initialize_rails_with_options :rails_root => '/path/somewhere', :environment => :development
100
+ end
101
+
102
+ end
103
+
104
+ BEGIN {
105
+ module DatabaseInitializationTestHelper
106
+
107
+ def start_database_initializer
108
+ start_database_initializer_with_options :adapter => "sqlite3", :dbfile => "foobar.sqlite3"
109
+ end
110
+
111
+ def start_database_initializer_with_options(options)
112
+ Adhearsion::Configuration.configure { |config| config.enable_database(options) }
113
+ Adhearsion::Initializer::DatabaseInitializer.start
114
+ end
115
+
116
+ def tempfile_with_contents(contents)
117
+ returning Tempfile.new("bogus_model") do |file|
118
+ file.puts contents
119
+ file.flush
120
+ end
121
+ end
122
+
123
+ def sample_user_model
124
+ <<-CODE
125
+ class User < ActiveRecord::Base
126
+ validates_uniqueness_of :name
127
+ end
128
+ CODE
129
+ end
130
+ end
131
+
132
+ module AsteriskInitializerTestHelper
133
+ def initialize_asterisk_with_defaults
134
+ initialize_asterisk_with_options Hash.new
135
+ end
136
+ def initialize_asterisk_with_options(options)
137
+ flexmock(Adhearsion::Initializer::AsteriskInitializer).should_receive(:join_server_thread_after_initialized)
138
+ Adhearsion::Configuration.configure { |config| config.enable_asterisk(options) }
139
+ Adhearsion::Initializer::AsteriskInitializer.start
140
+ end
141
+ end
142
+
143
+ module RailsInitializerTestHelper
144
+
145
+ def initialize_rails_with_options(options)
146
+ rails_options = flexmock "Rails options mock", options
147
+ flexstub(Adhearsion::AHN_CONFIG).should_receive(:rails).once.and_return(rails_options)
148
+ Adhearsion::Initializer::RailsInitializer.start
149
+ end
150
+
151
+ def stub_file_checking_methods!
152
+ flexstub(File).should_receive(:directory?).and_return true
153
+ flexstub(File).should_receive(:exists?).and_return true
154
+ end
155
+
156
+ def stub_before_call_hook!
157
+ flexstub(Adhearsion::Hooks::BeforeCall).should_receive :create_hook
158
+ end
159
+
160
+ end
161
+
162
+ }
@@ -0,0 +1,43 @@
1
+ require File.dirname(__FILE__) + "/../test_helper"
2
+
3
+ describe "Adhearsion::Paths" do
4
+
5
+ #TODO: All this crap will go away
6
+ disabled_test "should find all files when given a glob" do
7
+ inside_initialized_app do |path|
8
+ tmps = %w"foo.rb BA\ R.gem _q_a_z_.c"
9
+ tmps.each { |f| FileUtils.touch "#{path}/helpers/#{f}" }
10
+ found_helpers = all_helpers
11
+ all_helpers.should.not.be.empty
12
+ all_helpers.map! {|f| File.basename f }
13
+ all_helpers.each { |f| all_helpers.should.include(f) }
14
+ end
15
+ end
16
+ test "should find files when several globs are given"
17
+
18
+ test "should allow the removal of path managers" do
19
+ Adhearsion::Paths.manager_for :helpers, :directory => "helpers"
20
+ Adhearsion::Paths.remove_manager_for :helpers
21
+ end
22
+ end
23
+
24
+ describe "The .ahnrc " do
25
+ test "should allow ERb"
26
+ test "should create methods for every path declared"
27
+ test "should add all_x and x_path methods to main namespace and pluralize names" do
28
+ Adhearsion::Paths.manager_for "helper", :directory => "helpers"
29
+ should.respond_to(:all_helpers)
30
+ should.respond_to(:helper_path)
31
+ end
32
+ test "should have an init key"
33
+ test "should allow a String to the init key"
34
+ test "should default the init key to config/startup.rb"
35
+ test "should allow an Array to the init key"
36
+ end
37
+
38
+ describe "Adhearsion's paths syntax sugar" do
39
+ test "should calculate helper paths properly"
40
+ test "should find log files properly"
41
+ test "should find helper config paths properly"
42
+ test "should return the configuration for a helper properly"
43
+ end
data/spec/silence.rb ADDED
@@ -0,0 +1,10 @@
1
+ #
2
+ # Seeing the dump of pending specs every time you run them is distracting.
3
+ # This file lets you skip pending specs.
4
+ class Test::Unit::TestResult
5
+ def add_disabled(name)
6
+ #nothing!
7
+ end
8
+ end
9
+
10
+ Adhearsion::Logging.silence!
@@ -0,0 +1,149 @@
1
+ require File.dirname(__FILE__) + "/test_helper"
2
+ require 'adhearsion/cli'
3
+
4
+ module AhnCommandSpecHelper
5
+ def simulate_args(*args)
6
+ ARGV.clear
7
+ ARGV.concat args
8
+ end
9
+
10
+ def capture_stdout(&block)
11
+ old = $stdout
12
+ $stdout = io = StringIO.new
13
+ yield
14
+ ensure
15
+ $stdout = old
16
+ return io.string
17
+ end
18
+
19
+ def new_tmp_dir(filename=String.random)
20
+ File.join Dir.tmpdir, filename
21
+ end
22
+
23
+
24
+ end
25
+
26
+ context 'The Ahn Command helper' do
27
+
28
+ include AhnCommandSpecHelper
29
+
30
+ test "args are simulated properly" do
31
+ before = ARGV.clone
32
+ simulate_args "create", "/tmp/blah"
33
+ ARGV.should.not.equal before
34
+ end
35
+
36
+ test "STDOUT should be captured" do
37
+ capture_stdout do
38
+ puts "wee"
39
+ end.should.equal "wee\n"
40
+ end
41
+
42
+ end
43
+
44
+ context "A simulated use of the 'ahn' command" do
45
+
46
+ include AhnCommandSpecHelper
47
+
48
+ test "USAGE is defined" do
49
+ assert Adhearsion::CLI::AhnCommand.const_defined?('USAGE')
50
+ end
51
+
52
+ test "arguments to 'create' are executed properly properly" do
53
+ some_path = "/path/somewhere"
54
+ simulate_args "create", some_path
55
+ flexmock(Adhearsion::CLI::AhnCommand::CommandHandler).should_receive(:create).once.with(some_path, :default)
56
+ capture_stdout { Adhearsion::CLI::AhnCommand.execute! }
57
+ end
58
+
59
+ test "arguments to 'start' are executed properly properly" do
60
+ some_path = "/tmp/blargh"
61
+ simulate_args "start", some_path
62
+ flexmock(Adhearsion::CLI::AhnCommand::CommandHandler).should_receive(:start).once.with(some_path, false, nil)
63
+ Adhearsion::CLI::AhnCommand.execute!
64
+ end
65
+
66
+ test "should execute arguments to 'start' for daemonizing properly" do
67
+ somewhere = "/tmp/blarghh"
68
+ simulate_args "start", 'daemon', somewhere
69
+ flexmock(Adhearsion::CLI::AhnCommand::CommandHandler).should_receive(:start).once.with(somewhere, true, nil)
70
+ Adhearsion::CLI::AhnCommand.execute!
71
+ end
72
+
73
+ test 'parse_arguments should recognize start with daemon properly' do
74
+ path = '/path/to/somesuch'
75
+ arguments = ["start", 'daemon', path]
76
+ Adhearsion::CLI::AhnCommand.parse_arguments(arguments).should == [:start, path, true, nil]
77
+ end
78
+
79
+ test 'should recognize start with daemon and pid file properly' do
80
+ project_path = '/second/star/on/the/right'
81
+ pid_file_path = '/straight/on/til/morning'
82
+ arguments = ["start", "daemon", project_path, "--pid-file=#{pid_file_path}"]
83
+ Adhearsion::CLI::AhnCommand.parse_arguments(arguments).should == [:start, project_path, true, pid_file_path]
84
+ end
85
+
86
+ test 'parse_arguments should recognize start without daemon properly' do
87
+ path = '/path/to/somewhere'
88
+ arguments = ['start', path]
89
+ Adhearsion::CLI::AhnCommand.parse_arguments(arguments).should == [:start, path, false, nil]
90
+ end
91
+
92
+ test "if no path is provided, running Ahn command blows up" do
93
+ the_following_code {
94
+ Adhearsion::CLI::AhnCommand.parse_arguments(['start'])
95
+ }.should.raise Adhearsion::CLI::AhnCommand::CommandHandler::UnknownCommand
96
+ end
97
+
98
+ test "printing the version" do
99
+ capture_stdout do
100
+ simulate_args 'version'
101
+ Adhearsion::CLI::AhnCommand.execute!
102
+ end.should =~ Regexp.new(Regexp.escape(Adhearsion::VERSION::STRING))
103
+ end
104
+
105
+ test "printing the help" do
106
+ capture_stdout do
107
+ simulate_args 'help'
108
+ Adhearsion::CLI::AhnCommand.execute!
109
+ end.should =~ Regexp.new(Regexp.escape(Adhearsion::CLI::AhnCommand::USAGE))
110
+ end
111
+
112
+ test "reacting to unrecognized commands" do
113
+ the_following_code {
114
+ simulate_args "alpha", "beta"
115
+ Adhearsion::CLI::AhnCommand.execute!
116
+ }.should.raise(Adhearsion::CLI::AhnCommand::CommandHandler::UnknownCommand)
117
+ end
118
+
119
+ test "giving a path that doesn't contain a project raises an exception" do
120
+ the_following_code {
121
+ simulate_args "start", "/asjdfas/sndjfabsdfbqwb/qnjwejqbwh"
122
+ Adhearsion::CLI::AhnCommand.execute!
123
+ }.should.raise(Adhearsion::CLI::AhnCommand::CommandHandler::PathInvalid)
124
+ end
125
+
126
+ test "giving an unrecognized project name raises an exception" do
127
+ the_following_code {
128
+ nonexistent_app_name, nonexistent_path = "a2n8y3gny2", "/tmp/qjweqbwas"
129
+ simulate_args "create:#{nonexistent_app_name}", nonexistent_path
130
+ Adhearsion::CLI::AhnCommand.execute!
131
+ }.should.raise Adhearsion::CLI::AhnCommand::CommandHandler::UnknownProject
132
+ end
133
+ end
134
+
135
+ context 'A real use of the "ahn" command' do
136
+
137
+ include AhnCommandSpecHelper
138
+
139
+ test "the 'create' command" do
140
+ the_following_code {
141
+ tmp_path = new_tmp_dir
142
+ simulate_args "create", tmp_path
143
+ RubiGen::Base.default_options.merge! :quiet => true
144
+ capture_stdout { Adhearsion::CLI::AhnCommand.execute! }
145
+ File.exists?(File.join(tmp_path, ".ahnrc")).should.be true
146
+ }.should.not.raise
147
+ end
148
+
149
+ end
@@ -0,0 +1,87 @@
1
+ # #!/usr/bin/env spec
2
+ #
3
+ # # TODO: Forget regexps. Use Rubinius.
4
+ # # This spec is somewhat unique. It essentially reads the code
5
+ # # and ensures the best practices are followed.
6
+ #
7
+ # # TODO: Create a be_a_proper_method_definition assertion
8
+ # # TODO: Create a syntax checking spec
9
+ # # TODO: Report code that has spaces between the dot when defining the method on an object
10
+ #
11
+ # module CodeQualityHelper
12
+ # # TODO: Allow strings with a Hash in them before it
13
+ #
14
+ # BadMethodRegexp = /def\s+([$@]?[a-zA-Z_][\w_]*\s*\.\s*)?[a-zA-Z_][\w_]*[=!?]?[^(^\Z]/
15
+ # @root = File.dirname(__FILE__) + "/.."
16
+ #
17
+ # def ruby_files
18
+ # @ruby_files ||= Dir[@root + "/**/*.rb"].map { |f| File.expand_path f }
19
+ # end
20
+ #
21
+ # end
22
+ #
23
+ # describe "My 'bad method definition' finding regular expression" do
24
+ #
25
+ # # ATTENTION: If this spec ever blows up for a method definition it shouldn't,
26
+ # # please add the definition that caused it to explode here as an assertion.
27
+ # # It would also be nice to fix the regular expression too :)
28
+ #
29
+ # include CodeQualityHelper
30
+ #
31
+ # it "should NOT match method definitions with no arguments" do
32
+ # "def foo".should !~ CodeQualityHelper::BadMethodRegexp
33
+ # " def monkey ".should !~ CodeQualityHelper::BadMethodRegexp
34
+ # ' unless "#{bar}".empty? then def @zebra.spock '.should !~ CodeQualityHelper::BadMethodRegexp
35
+ # end
36
+ #
37
+ # it "should NOT match method definitions with arguments and parenthesis" do
38
+ # "def foo(bar)".should !~ CodeQualityHelper::BadMethodRegexp
39
+ # "\tdef $MONKEY . foo( bar, qaz = blam!) ".should !~ CodeQualityHelper::BadMethodRegexp
40
+ # "if(this) then def $MONKEY . foo( qaz = blam!, *args, &b) ".should !~ CodeQualityHelper::BadMethodRegexp
41
+ # " @something.each do |x| def something".should !~ CodeQualityHelper::BadMethodRegexp
42
+ # end
43
+ #
44
+ # it "should match method definitions with a space between the name and parenthesis" do
45
+ # "def foo (bar)".should =~ CodeQualityHelper::BadMethodRegexp
46
+ # "def \t m \t (*args)".should =~ CodeQualityHelper::BadMethodRegexp
47
+ # end
48
+ #
49
+ # it "should match method definitions with no parenthesis around its arguments" do
50
+ # "def foo bar".should =~ CodeQualityHelper::BadMethodRegexp
51
+ # "\tif $x then def foo bar # Commentacular".should =~ CodeQualityHelper::BadMethodRegexp
52
+ # end
53
+ # end
54
+ #
55
+ # describe "All method definitions" do
56
+ #
57
+ # include CodeQualityHelper
58
+ #
59
+ # before:all do
60
+ # @root = File.dirname(__FILE__) + "/.."
61
+ # end
62
+ #
63
+ # it "should have parenthesis around their arguments" do
64
+ # ruby_files.each do |file|
65
+ # puts file
66
+ # File.read(file).grep(CodeQualityHelper::BadMethodRegexp).should be_empty
67
+ # end
68
+ # end
69
+ # end
70
+ #
71
+ # # describe "The syntax of all Ruby source files" do
72
+ # #
73
+ # # include CodeQualityHelper
74
+ # #
75
+ # # before:all do
76
+ # # @root = File.dirname(__FILE__) + "/.."
77
+ # # end
78
+ # #
79
+ # # it "should be valid" do
80
+ # # incorrect = ruby_files.map { |f| File.expand_path f }.select do |file|
81
+ # # `ruby -c #{file}`
82
+ # # not $?.success?
83
+ # # end
84
+ # #
85
+ # # incorrect.should be_empty
86
+ # # end
87
+ # # end
@@ -0,0 +1,97 @@
1
+ require File.dirname(__FILE__) + "/test_helper"
2
+
3
+ context "Adding call context to components" do
4
+ include CallContextComponentTestHelpers
5
+
6
+ attr_reader :sample_component
7
+
8
+ setup do
9
+ @sample_component = new_componenet_class_named(sample_component_name)
10
+ end
11
+
12
+ test "Component name is added to list of components that will have call contexts injected into them" do
13
+ components_with_call_context.should.be.empty
14
+ the_following_code {
15
+ sample_component.add_call_context
16
+ }.should.not.raise
17
+
18
+ components_with_call_context.should.not.be.empty
19
+ Adhearsion::ComponentManager.components_with_call_context[sample_component_name].component_class.should.equal sample_component
20
+ end
21
+
22
+ private
23
+ def components_with_call_context
24
+ Adhearsion::ComponentManager.components_with_call_context.keys
25
+ end
26
+
27
+ def sample_component_name
28
+ 'SampleComponent'
29
+ end
30
+ end
31
+
32
+ context "Referencing a component class in a dial plan context" do
33
+ include CallContextComponentTestHelpers
34
+
35
+ test "the class constant should be available in the scope of a call context" do
36
+ sample_component_class = new_componenet_class_named('SampleComponent2')
37
+ sample_component_class.add_call_context
38
+
39
+ loader = load_dial_plan(<<-DIAL_PLAN)
40
+ some_context {
41
+ SampleComponent2
42
+ }
43
+ DIAL_PLAN
44
+
45
+ flexmock(Adhearsion::DialPlan::Loader).should_receive(:load_dial_plan).and_return(loader)
46
+ tested_call = Adhearsion::Call.new(nil, :context => :some_context)
47
+ mock_config = flexmock 'a Configuration which communicates automatically_answer_incoming_calls properly',
48
+ :automatically_answer_incoming_calls => false
49
+ flexmock(Adhearsion::Configuration).should_receive(:new).once.and_return mock_config
50
+ Adhearsion::Configuration.configure
51
+
52
+ the_following_code {
53
+ handle(tested_call)
54
+ }.should.not.raise
55
+ end
56
+
57
+ test "the call context is injected into any instances of the component class" do
58
+ sample_component_class = new_componenet_class_named('SampleComponent3')
59
+ sample_component_class.add_call_context :as => :call_context_variable_name
60
+
61
+ loader = load_dial_plan(<<-DIAL_PLAN)
62
+ some_context {
63
+ new_sample_component3.call_context_variable_name
64
+ }
65
+ DIAL_PLAN
66
+
67
+ flexmock(Adhearsion::DialPlan::Loader).should_receive(:load_dial_plan).and_return(loader)
68
+ sample_call = Adhearsion::Call.new(nil, :context => :some_context)
69
+ mock_config = flexmock 'a Configuration which communicates automatically_answer_incoming_calls properly',
70
+ :automatically_answer_incoming_calls => false
71
+ flexmock(Adhearsion::Configuration).should_receive(:new).once.and_return mock_config
72
+ Adhearsion::Configuration.configure
73
+
74
+ the_following_code {
75
+ handle(sample_call)
76
+ }.should.not.raise
77
+ end
78
+
79
+ private
80
+ def load_dial_plan(dial_plan_as_string)
81
+ Adhearsion::DialPlan::Loader.load(dial_plan_as_string)
82
+ end
83
+
84
+ def handle(call)
85
+ Adhearsion::DialPlan::Manager.handle(call)
86
+ end
87
+ end
88
+
89
+ BEGIN {
90
+ module CallContextComponentTestHelpers
91
+ def new_componenet_class_named(component_name)
92
+ component_namespace = Adhearsion::Components::ComponentModule.new('passed in component does not matter here')
93
+ Adhearsion::Components::Component.prepare_component_class(component_namespace, component_name)
94
+ component_namespace.const_get(component_name)
95
+ end
96
+ end
97
+ }
@@ -0,0 +1,8 @@
1
+ require File.dirname(__FILE__) + "/test_helper"
2
+
3
+ context "The Adhearsion module" do
4
+ # This test is of questionable benefit
5
+ test "should have a VERSION constant" do
6
+ assert(Adhearsion.const_defined?(:VERSION), "VERSION constant should be defined")
7
+ end
8
+ end
data/spec/test_drb.rb ADDED
@@ -0,0 +1,104 @@
1
+ require File.dirname(__FILE__) + "/test_helper"
2
+
3
+ # The way I envisoned publishing this DRb:
4
+ #
5
+ # publish :globally do/end
6
+ # publish :with => :drb do/end
7
+
8
+ context "Publishing an interface" do
9
+ test "should be allowed with a class method" do
10
+ Class.new.class_eval do
11
+ include Adhearsion::Publishable
12
+ publish :through => :interface do
13
+ def self.bar
14
+ [1, 2, 3]
15
+ end
16
+ end
17
+ end
18
+ Adhearsion::DrbDoor.instance.interface.bar.should.equal [1, 2, 3]
19
+ end
20
+
21
+ test "should be allowed with an alternate interface" do
22
+ Class.new.class_eval do
23
+ include Adhearsion::Publishable
24
+ publish :through => :api do
25
+ def self.bar
26
+ [2, 3, 4]
27
+ end
28
+ end
29
+ end
30
+ Adhearsion::DrbDoor.instance.api.bar.should.equal [2, 3, 4]
31
+ end
32
+
33
+ test "should be allowed with a metaclass block" do
34
+ Class.new.class_eval do
35
+ include Adhearsion::Publishable
36
+ publish :through => :interface do
37
+ class << self
38
+ def bar
39
+ [3, 2, 1]
40
+ end
41
+ end
42
+ end
43
+ end
44
+ Adhearsion::DrbDoor.instance.interface.bar.should.equal [3, 2, 1]
45
+ end
46
+
47
+ test "should be allowed from within the metaclass block" do
48
+ # Class.new.class_eval do
49
+ # include Publishable
50
+ # class << self
51
+ # publish :through => :interface do
52
+ # def baz
53
+ # [4, 5, 6]
54
+ # end
55
+ # end
56
+ # end
57
+ # end
58
+ # Adhearsion::DrbDoor.instance.interface.baz.should.equal [4, 5, 6]
59
+ end
60
+ end
61
+
62
+ context "Invoking an interface" do
63
+ test "should raise an exception if the method is not found" do
64
+ the_following_code do
65
+ Adhearsion::DrbDoor.instance.interface.foobar.should.equal [1, 2, 3]
66
+ end.should.raise NoMethodError
67
+ end
68
+
69
+ test "should raise an exception if the interface is not found" do
70
+ the_following_code do
71
+ Adhearsion::DrbDoor.instance.bad_interface.bar.should.equal [1, 2, 3]
72
+ end.should.raise NoMethodError
73
+ end
74
+ end
75
+
76
+ context "Invoking an interface method via DRb" do
77
+ require 'drb'
78
+ before do
79
+ @door = DRb.start_service "druby://127.0.0.1:9050", Adhearsion::DrbDoor.instance
80
+ end
81
+
82
+ test "should return the proper result" do
83
+ client = DRbObject.new nil, DRb.uri
84
+ client.interface.bar.should.equal [3, 2, 1]
85
+ end
86
+
87
+ test "should raise an exception for a non-existent interface" do
88
+ client = DRbObject.new nil, DRb.uri
89
+ the_following_code do
90
+ client.interface.bad_interface.should.equal [3, 2, 1]
91
+ end.should.raise NoMethodError
92
+ end
93
+
94
+ test "should raise an exception for a non-existent method" do
95
+ client = DRbObject.new nil, DRb.uri
96
+ the_following_code do
97
+ client.interface.interface.foobar.equal [3, 2, 1]
98
+ end.should.raise NoMethodError
99
+ end
100
+
101
+ after do
102
+ DRb.stop_service
103
+ end
104
+ end