adhearsion 1.0.1 → 1.0.2

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 (64) hide show
  1. data/.gitignore +10 -0
  2. data/CHANGELOG +8 -0
  3. data/README.markdown +33 -0
  4. data/Rakefile +28 -68
  5. data/adhearsion.gemspec +19 -133
  6. data/app_generators/ahn/templates/Gemfile +0 -4
  7. data/app_generators/ahn/templates/components/disabled/restful_rpc/spec/restful_rpc_spec.rb +4 -16
  8. data/lib/adhearsion/cli.rb +17 -0
  9. data/lib/adhearsion/component_manager/component_tester.rb +1 -3
  10. data/lib/adhearsion/component_manager/spec_framework.rb +4 -10
  11. data/lib/adhearsion/foundation/object.rb +10 -0
  12. data/lib/adhearsion/version.rb +1 -1
  13. data/spec/ahn_command_spec.rb +284 -0
  14. data/spec/component_manager_spec.rb +292 -0
  15. data/spec/constants_spec.rb +8 -0
  16. data/spec/drb_spec.rb +65 -0
  17. data/spec/fixtures/dialplan.rb +3 -0
  18. data/spec/foundation/event_socket_spec.rb +168 -0
  19. data/spec/host_definitions_spec.rb +79 -0
  20. data/spec/initialization_spec.rb +163 -0
  21. data/spec/initializer/configuration_spec.rb +270 -0
  22. data/spec/initializer/loading_spec.rb +149 -0
  23. data/spec/initializer/paths_spec.rb +74 -0
  24. data/spec/logging_spec.rb +86 -0
  25. data/spec/relationship_properties_spec.rb +54 -0
  26. data/spec/silence.rb +10 -0
  27. data/spec/spec_helper.rb +101 -0
  28. data/spec/voip/asterisk/agi_server_spec.rb +473 -0
  29. data/spec/voip/asterisk/ami/ami_spec.rb +549 -0
  30. data/spec/voip/asterisk/ami/lexer/ami_fixtures.yml +30 -0
  31. data/spec/voip/asterisk/ami/lexer/lexer_story +291 -0
  32. data/spec/voip/asterisk/ami/lexer/lexer_story.rb +241 -0
  33. data/spec/voip/asterisk/ami/lexer/story_helper.rb +124 -0
  34. data/spec/voip/asterisk/ami/old_tests.rb +204 -0
  35. data/spec/voip/asterisk/ami/super_manager/super_manager_story +25 -0
  36. data/spec/voip/asterisk/ami/super_manager/super_manager_story.rb +15 -0
  37. data/spec/voip/asterisk/ami/super_manager/super_manager_story_helper.rb +5 -0
  38. data/spec/voip/asterisk/commands_spec.rb +2179 -0
  39. data/spec/voip/asterisk/config_file_generators/agents_spec.rb +251 -0
  40. data/spec/voip/asterisk/config_file_generators/queues_spec.rb +323 -0
  41. data/spec/voip/asterisk/config_file_generators/voicemail_spec.rb +306 -0
  42. data/spec/voip/asterisk/config_manager_spec.rb +127 -0
  43. data/spec/voip/asterisk/menu_command/calculated_match_spec.rb +109 -0
  44. data/spec/voip/asterisk/menu_command/matchers_spec.rb +97 -0
  45. data/spec/voip/call_routing_spec.rb +125 -0
  46. data/spec/voip/dialplan_manager_spec.rb +468 -0
  47. data/spec/voip/dsl/dialing_dsl_spec.rb +270 -0
  48. data/spec/voip/dsl/dispatcher_spec.rb +82 -0
  49. data/spec/voip/dsl/dispatcher_spec_helper.rb +45 -0
  50. data/spec/voip/dsl/parser_spec.rb +69 -0
  51. data/spec/voip/freeswitch/basic_connection_manager_spec.rb +39 -0
  52. data/spec/voip/freeswitch/inbound_connection_manager_spec.rb +39 -0
  53. data/spec/voip/freeswitch/oes_server_spec.rb +9 -0
  54. data/spec/voip/numerical_string_spec.rb +61 -0
  55. data/spec/voip/phone_number_spec.rb +45 -0
  56. data/theatre-spec/dsl_examples/dynamic_stomp.rb +7 -0
  57. data/theatre-spec/dsl_examples/simple_before_call.rb +7 -0
  58. data/theatre-spec/dsl_spec.rb +43 -0
  59. data/theatre-spec/invocation_spec.rb +167 -0
  60. data/theatre-spec/namespace_spec.rb +125 -0
  61. data/theatre-spec/spec_helper.rb +37 -0
  62. data/theatre-spec/spec_helper_spec.rb +28 -0
  63. data/theatre-spec/theatre_class_spec.rb +150 -0
  64. metadata +171 -34
@@ -47,9 +47,7 @@ module ComponentTester
47
47
 
48
48
  def initialize!
49
49
  metadata = component_module.metaclass.send(:instance_variable_get, :@metadata)
50
- if metadata && metadata[:initialization_block].kind_of?(Proc)
51
- metadata[:initialization_block].call
52
- end
50
+ metadata[:initialization_block].call if metadata && metadata[:initialization_block].kind_of?(Proc)
53
51
  end
54
52
 
55
53
  end
@@ -1,14 +1,8 @@
1
1
  require 'adhearsion/component_manager/component_tester'
2
2
  begin
3
- require 'spec'
3
+ require 'rspec'
4
4
  rescue LoadError
5
- abort 'You do not have the "rspec" gem installed! You must install it to continue.\n\nsudo gem install rspec\n\n'
6
- end
7
-
8
- begin
9
- require 'rr'
10
- rescue LoadError
11
- abort 'You do not have the "rr" gem installed! You must install it to continue.\n\nsudo gem install rr\n\n'
5
+ abort "You do not have the 'rspec' gem installed! You must install it to continue.\n\nsudo gem install rspec\n\n"
12
6
  end
13
7
 
14
8
  module ComponentConfigurationSpecHelper
@@ -18,7 +12,7 @@ module ComponentConfigurationSpecHelper
18
12
  end
19
13
  end
20
14
 
21
- Spec::Runner.configure do |config|
22
- config.mock_with :rr
15
+ RSpec.configure do |config|
16
+ config.mock_with :rspec
23
17
  config.include ComponentConfigurationSpecHelper
24
18
  end
@@ -0,0 +1,10 @@
1
+ # Monkey patch Object to support the #tap method.
2
+ # This method is present in Ruby 1.8.7 and later.
3
+ if !Object.respond_to?(:tap)
4
+ class Object
5
+ def tap
6
+ yield self
7
+ self
8
+ end
9
+ end
10
+ end
@@ -2,7 +2,7 @@ module Adhearsion #:nodoc:
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 1 unless defined? MAJOR
4
4
  MINOR = 0 unless defined? MINOR
5
- TINY = 1 unless defined? TINY
5
+ TINY = 2 unless defined? TINY
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.') unless defined? STRING
8
8
  end
@@ -0,0 +1,284 @@
1
+ require 'spec_helper'
2
+ require 'adhearsion/cli'
3
+
4
+ module AhnCommandSpecHelper
5
+
6
+ def simulate_args(*args)
7
+ ARGV.clear
8
+ ARGV.concat args
9
+ end
10
+
11
+ def capture_stdout(&block)
12
+ old = $stdout
13
+ $stdout = io = StringIO.new
14
+ yield
15
+ ensure
16
+ $stdout = old
17
+ return io.string
18
+ end
19
+
20
+ def new_tmp_dir(filename=new_guid)
21
+ File.join Dir.tmpdir, filename
22
+ end
23
+
24
+ def create_component_sandbox
25
+ new_tmp_dir.tap do |dir|
26
+ Dir.mkdir dir
27
+ FileUtils.touch dir + "/.ahnrc"
28
+ Dir.mkdir dir + "/components"
29
+ end
30
+ end
31
+
32
+ def execute_ahn_command
33
+ Adhearsion::CLI::AhnCommand.execute!
34
+ end
35
+
36
+ def executing_ahn_command_should_fail_with(exception)
37
+ flexmock(Adhearsion::CLI::AhnCommand).should_receive(:fail_and_print_usage).with(exception).once
38
+ execute_ahn_command
39
+ end
40
+
41
+ end
42
+
43
+ describe 'The Ahn Command helper' do
44
+
45
+ include AhnCommandSpecHelper
46
+
47
+ it "args are simulated properly" do
48
+ before = ARGV.clone
49
+ simulate_args "create", "/tmp/blah"
50
+ ARGV.should_not be before
51
+ end
52
+
53
+ it "STDOUT should be captured" do
54
+ capture_stdout do
55
+ puts "wee"
56
+ end.should == "wee\n"
57
+ end
58
+
59
+ end
60
+
61
+ describe "A simulated use of the 'ahn' command" do
62
+
63
+ include AhnCommandSpecHelper
64
+
65
+ it "USAGE is defined" do
66
+ Adhearsion::CLI::AhnCommand.const_defined?('USAGE').should be true
67
+ end
68
+
69
+ it "arguments to 'create' are executed properly" do
70
+ some_path = "/path/somewhere"
71
+ simulate_args "create", some_path
72
+ flexmock(Adhearsion::CLI::AhnCommand::CommandHandler).should_receive(:create).once.with(some_path)
73
+ capture_stdout { Adhearsion::CLI::AhnCommand.execute! }
74
+ end
75
+
76
+ it "arguments to 'start' are executed properly properly" do
77
+ some_path = "/tmp/blargh"
78
+ simulate_args "start", some_path
79
+ flexmock(Adhearsion::CLI::AhnCommand::CommandHandler).should_receive(:start).once.with(some_path, false, nil)
80
+ Adhearsion::CLI::AhnCommand.execute!
81
+ end
82
+
83
+ it "should execute arguments to 'start' for daemonizing properly" do
84
+ somewhere = "/tmp/blarghh"
85
+ simulate_args "start", 'daemon', somewhere
86
+ flexmock(Adhearsion::CLI::AhnCommand::CommandHandler).should_receive(:start).once.with(somewhere, true, nil)
87
+ Adhearsion::CLI::AhnCommand.execute!
88
+ end
89
+
90
+ it 'parse_arguments should recognize start with daemon properly' do
91
+ path = '/path/to/somesuch'
92
+ arguments = ["start", 'daemon', path]
93
+ Adhearsion::CLI::AhnCommand.parse_arguments(arguments).should == [:start, path, true, nil]
94
+ end
95
+
96
+ it 'should recognize start with daemon and pid file properly' do
97
+ project_path = '/second/star/on/the/right'
98
+ pid_file_path = '/straight/on/til/morning'
99
+ arguments = ["start", "daemon", project_path, "--pid-file=#{pid_file_path}"]
100
+ Adhearsion::CLI::AhnCommand.parse_arguments(arguments).should == [:start, project_path, true, pid_file_path]
101
+ end
102
+
103
+ it 'parse_arguments should recognize start without daemon properly' do
104
+ path = '/path/to/somewhere'
105
+ arguments = ['start', path]
106
+ Adhearsion::CLI::AhnCommand.parse_arguments(arguments).should == [:start, path, false, nil]
107
+ end
108
+
109
+ it "if no path is provided, running Ahn command blows up" do
110
+ flexmock(Adhearsion::CLI::AhnCommand).should_receive(:fail_and_print_usage).once.and_return
111
+ Adhearsion::CLI::AhnCommand.parse_arguments(['start'])
112
+ end
113
+
114
+ it "printing the version" do
115
+ capture_stdout do
116
+ simulate_args 'version'
117
+ Adhearsion::CLI::AhnCommand.execute!
118
+ end.should =~ Regexp.new(Regexp.escape(Adhearsion::VERSION::STRING))
119
+ end
120
+
121
+ it "printing the help" do
122
+ capture_stdout do
123
+ simulate_args 'help'
124
+ Adhearsion::CLI::AhnCommand.execute!
125
+ end.should =~ Regexp.new(Regexp.escape(Adhearsion::CLI::AhnCommand::USAGE))
126
+ end
127
+
128
+ it "reacting to unrecognized commands" do
129
+ simulate_args "alpha", "beta"
130
+ flexmock(Adhearsion::CLI::AhnCommand).should_receive(:fail_and_print_usage).once.and_return
131
+ Adhearsion::CLI::AhnCommand.execute!
132
+ end
133
+
134
+ it "giving a path that doesn't contain a project raises an exception" do
135
+ simulate_args "start", "/asjdfas/sndjfabsdfbqwb/qnjwejqbwh"
136
+ executing_ahn_command_should_fail_with Adhearsion::CLI::AhnCommand::CommandHandler::PathInvalid
137
+ end
138
+
139
+ end
140
+
141
+ describe "Component-related commands" do
142
+
143
+ include AhnCommandSpecHelper
144
+
145
+
146
+ it "should move a folder from the components/disabled/ folder of an app to the components/ directory if it exists" do
147
+ sandbox = create_component_sandbox
148
+ disabled_dir = "#{sandbox}/components/disabled/foobar"
149
+ enabled_dir = "#{sandbox}/components/foobar"
150
+
151
+ FileUtils.mkdir_p disabled_dir
152
+ FileUtils.touch disabled_dir + "/foobar.rb"
153
+
154
+ flexmock(Dir).should_receive(:pwd).once.and_return disabled_dir
155
+
156
+ simulate_args "enable", "component", "foobar"
157
+ capture_stdout { execute_ahn_command }
158
+
159
+ File.directory?(disabled_dir).should_not be true
160
+ File.exists?(enabled_dir + "/foobar.rb").should be true
161
+ end
162
+
163
+ it "should raise a ComponentError exception if there is no disabled folder" do
164
+ sandbox = create_component_sandbox
165
+
166
+ flexmock(Dir).should_receive(:pwd).once.and_return sandbox
167
+
168
+ simulate_args "enable", "component", "foo"
169
+
170
+ executing_ahn_command_should_fail_with Adhearsion::CLI::AhnCommand::CommandHandler::ComponentError
171
+ end
172
+
173
+ it "should raise an exception if the disabled component exists and there's an enabled component of the same name" do
174
+ sandbox = create_component_sandbox
175
+
176
+ flexmock(Dir).should_receive(:pwd).once.and_return sandbox
177
+
178
+ FileUtils.mkdir_p sandbox + "/disabled/lolcats"
179
+ FileUtils.mkdir_p sandbox + "/lolcats"
180
+
181
+ simulate_args "enable", "component", "foo"
182
+
183
+ executing_ahn_command_should_fail_with Adhearsion::CLI::AhnCommand::CommandHandler::ComponentError
184
+ end
185
+
186
+ it "should raise a PathInvalid error if the current directory does not belong to an Adhearsion app" do
187
+ flexmock(Dir).should_receive("pwd").and_return "/"
188
+ simulate_args "enable", "component", "foo"
189
+ executing_ahn_command_should_fail_with Adhearsion::CLI::AhnCommand::CommandHandler::PathInvalid
190
+ end
191
+
192
+ it "should properly create the disabled folder if it doesn't exist when disabling a component" do
193
+ sandbox = create_component_sandbox
194
+ flexmock(Dir).should_receive(:pwd).once.and_return sandbox
195
+
196
+ FileUtils.mkdir_p sandbox + "/components/rickroller"
197
+
198
+ simulate_args 'disable', 'component', 'rickroller'
199
+ capture_stdout { execute_ahn_command }
200
+ File.directory?(sandbox + "/components/disabled/rickroller").should be true
201
+ File.directory?(sandbox + "/components/rickroller").should be false
202
+ end
203
+
204
+ it "should raise an UnknownCommand error when trying to enable a kind of feature which doesn't exist" do
205
+ simulate_args "enable", "bonobo"
206
+ executing_ahn_command_should_fail_with Adhearsion::CLI::AhnCommand::CommandHandler::UnknownCommand
207
+ end
208
+
209
+ it "should raise an UnknownCommand error when trying to disable a kind of feature which doesn't exist" do
210
+ simulate_args "disable", "thanksgiving_dinner"
211
+ executing_ahn_command_should_fail_with Adhearsion::CLI::AhnCommand::CommandHandler::UnknownCommand
212
+ end
213
+
214
+ it "should raise a ComponentError when the component to disable doesn't exist" do
215
+ sandbox = create_component_sandbox
216
+ flexmock(Dir).should_receive(:pwd).once.and_return sandbox
217
+
218
+ simulate_args "disable", "component", "monkeybars"
219
+ executing_ahn_command_should_fail_with Adhearsion::CLI::AhnCommand::CommandHandler::ComponentError
220
+ end
221
+
222
+ it "should raise an exception when disabling a component and the component's disabled directory already exists" do
223
+ sandbox = create_component_sandbox
224
+
225
+ flexmock(Dir).should_receive(:pwd).once.and_return sandbox
226
+
227
+ FileUtils.mkdir_p sandbox + "/disabled/lolcats"
228
+ FileUtils.mkdir_p sandbox + "/lolcats"
229
+
230
+ simulate_args "disable", "component", "foo"
231
+ executing_ahn_command_should_fail_with Adhearsion::CLI::AhnCommand::CommandHandler::ComponentError
232
+ end
233
+
234
+ end
235
+
236
+ describe 'The "create" command' do
237
+
238
+ include AhnCommandSpecHelper
239
+
240
+ it "creating a project" do
241
+ the_following_code {
242
+ tmp_path = new_tmp_dir
243
+ simulate_args "create", tmp_path
244
+ RubiGen::Base.default_options.merge! :quiet => true
245
+ # capture_stdout { Adhearsion::CLI::AhnCommand.execute! }
246
+ execute_ahn_command
247
+ File.exists?(File.join(tmp_path, ".ahnrc")).should be true
248
+ }.should_not raise_error
249
+ end
250
+
251
+ it "should raise an UnknownCommand if running create with no arguments" do
252
+ simulate_args "create"
253
+ executing_ahn_command_should_fail_with Adhearsion::CLI::AhnCommand::CommandHandler::UnknownCommand
254
+ end
255
+
256
+ it "should raise a ComponentError if the name of the component is not a valid Ruby symbol name" do
257
+ bad_names = ["!))", "37signals", "foo bar", "*"]
258
+ bad_names.each do |bad_name|
259
+ simulate_args "create", "component", bad_name
260
+ executing_ahn_command_should_fail_with Adhearsion::CLI::AhnCommand::CommandHandler::ComponentError
261
+ end
262
+ end
263
+
264
+ it "should raise a ComponentError if the component name already exists in the folder" do
265
+ sandbox = create_component_sandbox
266
+ Dir.mkdir sandbox + "/components/blehhh"
267
+ flexmock(Dir).should_receive(:pwd).once.and_return sandbox
268
+ simulate_args "create", "component", "blehhh"
269
+
270
+ executing_ahn_command_should_fail_with Adhearsion::CLI::AhnCommand::CommandHandler::ComponentError
271
+ end
272
+
273
+ it "should create a folder with matching .rb file and .yml file when all guards pass" do
274
+ sandbox = create_component_sandbox
275
+ flexmock(Dir).should_receive(:pwd).once.and_return sandbox
276
+
277
+ simulate_args "create", "component", "ohai"
278
+ capture_stdout { execute_ahn_command }
279
+
280
+ File.exists?(sandbox + "/components/ohai/lib/ohai.rb").should be true
281
+ File.exists?(sandbox + "/components/ohai/config/ohai.yml").should be true
282
+ end
283
+
284
+ end
@@ -0,0 +1,292 @@
1
+ require 'spec_helper'
2
+ require 'adhearsion/component_manager/component_tester'
3
+
4
+ module ComponentManagerTestHelper
5
+
6
+ def mock_component_config(component_name, yaml)
7
+ yaml = YAML.load(yaml) if yaml.kind_of?(String)
8
+ flexmock(@component_manager.lazy_config_loader).should_receive(component_name).and_return yaml
9
+ end
10
+
11
+ def run_component_code(code)
12
+ @component_manager.load_code(code)
13
+ end
14
+
15
+ def new_object_with_scope(scope)
16
+ @component_manager.extend_object_with(Object.new, scope)
17
+ end
18
+ end
19
+
20
+ describe "Adhearsion's component system" do
21
+
22
+ include ComponentManagerTestHelper
23
+
24
+ before :each do
25
+ @component_manager = Adhearsion::Components::ComponentManager.new "/filesystem/access/should/be/mocked/out"
26
+ Object.send :remove_const, :COMPONENTS if Object.const_defined?(:COMPONENTS)
27
+ Object.send :const_set, :COMPONENTS, @component_manager.lazy_config_loader
28
+ end
29
+
30
+ it "constants should be available in the main namespace" do
31
+ constant_name = "FOO_#{rand(10000000000)}"
32
+ begin
33
+ run_component_code <<-RUBY
34
+ #{constant_name} = 123
35
+ RUBY
36
+ Module.const_get(constant_name).should be 123
37
+ ensure
38
+ Object.send(:remove_const, constant_name) rescue nil
39
+ end
40
+ end
41
+
42
+ it "defined constants should be available within the methods_for block" do
43
+ constant_name = "I_HAVE_#{rand(100000000000000)}_GUMMY_BEARS"
44
+ code = <<-RUBY
45
+ #{constant_name} = :its_true!
46
+ methods_for :dialplan do
47
+ throw #{constant_name}
48
+ end
49
+ RUBY
50
+ the_following_code {
51
+ run_component_code code
52
+ }.should throw_symbol :its_true!
53
+ end
54
+
55
+ it "initialization block should be called after the methods_for() blocks"
56
+
57
+ it "defined methods should be recognized once defined" do
58
+ run_component_code <<-RUBY
59
+ methods_for :events do
60
+ def foo
61
+ :inside_foo!
62
+ end
63
+ end
64
+ RUBY
65
+ container_object = new_object_with_scope :events
66
+ container_object.foo.should be :inside_foo!
67
+ end
68
+
69
+ it "a method defined in one scope should not be available in another" do
70
+ code = <<-RUBY
71
+ methods_for :events do
72
+ def in_events
73
+ in_dialplan
74
+ end
75
+ end
76
+ methods_for :dialplan do
77
+ def in_dialplan
78
+ in_events
79
+ end
80
+ end
81
+ RUBY
82
+
83
+ end
84
+
85
+ it "methods defined in separate blocks should be available if they share a scope" do
86
+ run_component_code <<-RUBY
87
+ methods_for :dialplan do
88
+ def get_symbol
89
+ :i_am_the_best_symbol_in_the_world
90
+ end
91
+ end
92
+ methods_for :dialplan do
93
+ def throw_best_symbol_in_the_world
94
+ throw get_symbol
95
+ end
96
+ end
97
+ RUBY
98
+ obj = new_object_with_scope :dialplan
99
+ the_following_code {
100
+ obj.throw_best_symbol_in_the_world
101
+ }.should throw_symbol :i_am_the_best_symbol_in_the_world
102
+ end
103
+
104
+ it "privately defined methods should remain private" do
105
+ return_value = "hear! hear! i'm private, indeed!"
106
+ run_component_code <<-RUBY
107
+ methods_for :generators do
108
+ def i_am_public
109
+ i_am_private.reverse
110
+ end
111
+
112
+ private
113
+
114
+ def i_am_private
115
+ "#{return_value}"
116
+ end
117
+ end
118
+ RUBY
119
+ object = new_object_with_scope(:generators)
120
+ object.i_am_public.should == return_value.reverse
121
+ the_following_code {
122
+ object.i_am_private
123
+ }.should raise_error NoMethodError
124
+ end
125
+
126
+ it "load_components should load code with the proper filenames" do
127
+ components_dir_path = "/path/to/somewhere/components"
128
+ component_names = %w[fooo barr qazz]
129
+ component_paths = component_names.map { |name| "#{components_dir_path}/#{name}" }
130
+
131
+ flexmock(Dir).should_receive(:glob).once.with(components_dir_path + "/*").
132
+ and_return(component_paths + ["disabled"])
133
+ flexstub(File).should_receive(:exists?).and_return true
134
+ flexstub(File).should_receive(:directory?).and_return true
135
+
136
+ manager = Adhearsion::Components::ComponentManager.new(components_dir_path)
137
+ component_paths.each do |path|
138
+ flexmock(manager).should_receive(:load_file).once.with "#{path}/lib/#{File.basename(path)}.rb"
139
+ end
140
+
141
+ manager.load_components
142
+ end
143
+
144
+ it "the :global scope" do
145
+ run_component_code <<-RUBY
146
+ methods_for :global do
147
+ def i_should_be_globally_available
148
+ :found!
149
+ end
150
+ end
151
+ RUBY
152
+ @component_manager.globalize_global_scope!
153
+ i_should_be_globally_available.should be :found!
154
+ end
155
+
156
+ it "methods defined in outside of any scope should not be globally available" do
157
+ run_component_code <<-RUBY
158
+ def i_should_not_be_globally_available
159
+ :found!
160
+ end
161
+ RUBY
162
+ the_following_code {
163
+ i_should_not_be_globally_available
164
+ }.should raise_error NameError
165
+ end
166
+
167
+ it "should have access to the COMPONENTS constant" do
168
+ component_name = "am_not_for_kokoa"
169
+ mock_component_config(component_name, <<-YAML)
170
+ host: localhost
171
+ port: 7007
172
+ array:
173
+ - 1
174
+ - 2
175
+ - 3
176
+ YAML
177
+ run_component_code <<-RUBY
178
+ methods_for(:dialplan) do
179
+ def host
180
+ COMPONENTS.#{component_name}["host"]
181
+ end
182
+ def port
183
+ COMPONENTS.#{component_name}["port"]
184
+ end
185
+ def array
186
+ COMPONENTS.#{component_name}["array"]
187
+ end
188
+ end
189
+ RUBY
190
+ obj = new_object_with_scope :dialplan
191
+ obj.host.should =="localhost"
192
+ obj.port.should ==7007
193
+ obj.array.should ==[1,2,3]
194
+ end
195
+
196
+ it "the delegate method should properly delegate arguments and a block to a specified object" do
197
+ component_name = "writing_this_at_peets_coffee"
198
+ mock_component_config(component_name, "{jay: phillips}")
199
+ run_component_code <<-RUBY
200
+
201
+ initialization do
202
+ obj = Object.new
203
+ def obj.foo
204
+ :foo
205
+ end
206
+ def obj.bar
207
+ :bar
208
+ end
209
+ COMPONENTS.#{component_name}[:foobar] = obj
210
+ end
211
+
212
+ methods_for :dialplan do
213
+ delegate :#{component_name}, :to => :COMPONENTS
214
+ end
215
+ RUBY
216
+ obj = new_object_with_scope :dialplan
217
+ obj.send(component_name)[:foobar].foo.should be :foo
218
+ end
219
+
220
+ it "an initialized component should not have an 'initialize' private method since it's confusing"
221
+
222
+ it "should find components in a project properly"
223
+ it "should run the initialization block" do
224
+ code = <<-RUBY
225
+ initialization do
226
+ throw :got_here!
227
+ end
228
+ RUBY
229
+ the_following_code {
230
+ run_component_code code
231
+ }.should throw_symbol :got_here!
232
+
233
+ end
234
+
235
+ it "should alias the initialization method to initialisation" do
236
+ code = <<-RUBY
237
+ initialisation do
238
+ throw :BRITISH!
239
+ end
240
+ RUBY
241
+ the_following_code {
242
+ run_component_code code
243
+ }.should throw_symbol :BRITISH!
244
+ end
245
+
246
+ it "should properly expose any defined constants" do
247
+ container = run_component_code <<-RUBY
248
+ TEST_ONE = 1
249
+ TEST_TWO = 2
250
+ TEST_THREE = 3
251
+ RUBY
252
+ container.constants.sort.map{|s| s.to_sym}.should == [:TEST_ONE, :TEST_THREE, :TEST_TWO]
253
+ container.constants.map do |constant|
254
+ container.const_get(constant)
255
+ end.sort.should ==[1,2,3]
256
+ end
257
+
258
+ end
259
+
260
+ describe "ComponentTester" do
261
+ it "should allow the scope-resolution operator to access a component's constants" do
262
+ component_name = "my_awesomeness"
263
+ flexmock(File).should_receive(:read).once.with(/#{component_name}\.rb$/).and_return "AWESOME = :YES!"
264
+ tester = ComponentTester.new(component_name, "/path/shouldnt/matter")
265
+ tester::AWESOME.should be :YES!
266
+ end
267
+
268
+ it "should return an executable helper method properly" do
269
+ component_name = "one_two_three"
270
+ flexmock(File).should_receive(:read).once.with(/#{component_name}\.rb$/).and_return "def hair() :long end"
271
+ tester = ComponentTester.new(component_name, "/path/shouldnt/matter")
272
+ tester.helper_method(:hair).call.should be :long
273
+ end
274
+
275
+ it "should load the configuration for the given helper properly" do
276
+ component_name = "i_like_configurations"
277
+ config = {:german => {1 => :eins, 2 => :zwei, 3 => :drei}}
278
+ flexmock(File).should_receive(:read).once.with(/#{component_name}\.rb$/).and_return ""
279
+ component_manager = flexmock "ComponentManager"
280
+ component_manager.should_receive(:configuration_for_component_named).once.with(component_name).and_return config
281
+ flexmock(Adhearsion::Components::ComponentManager).should_receive(:new).once.and_return component_manager
282
+ ComponentTester.new(component_name, "/path/shouldnt/matter").config[:german][1].should be :eins
283
+ end
284
+
285
+ it "should execute the initialize block when calling ComponentTester#initialize!()" do
286
+ component_name = "morrissey"
287
+ flexmock(File).should_receive(:read).once.with(/#{component_name}\.rb$/).and_return "initialization { $YES_I_WAS_CALLED = TRUE }"
288
+ ComponentTester.new(component_name, "/path/shouldnt/matter").initialize!
289
+ $YES_I_WAS_CALLED.should == true
290
+ end
291
+
292
+ end