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.
- data/.gitignore +10 -0
- data/CHANGELOG +8 -0
- data/README.markdown +33 -0
- data/Rakefile +28 -68
- data/adhearsion.gemspec +19 -133
- data/app_generators/ahn/templates/Gemfile +0 -4
- data/app_generators/ahn/templates/components/disabled/restful_rpc/spec/restful_rpc_spec.rb +4 -16
- data/lib/adhearsion/cli.rb +17 -0
- data/lib/adhearsion/component_manager/component_tester.rb +1 -3
- data/lib/adhearsion/component_manager/spec_framework.rb +4 -10
- data/lib/adhearsion/foundation/object.rb +10 -0
- data/lib/adhearsion/version.rb +1 -1
- data/spec/ahn_command_spec.rb +284 -0
- data/spec/component_manager_spec.rb +292 -0
- data/spec/constants_spec.rb +8 -0
- data/spec/drb_spec.rb +65 -0
- data/spec/fixtures/dialplan.rb +3 -0
- data/spec/foundation/event_socket_spec.rb +168 -0
- data/spec/host_definitions_spec.rb +79 -0
- data/spec/initialization_spec.rb +163 -0
- data/spec/initializer/configuration_spec.rb +270 -0
- data/spec/initializer/loading_spec.rb +149 -0
- data/spec/initializer/paths_spec.rb +74 -0
- data/spec/logging_spec.rb +86 -0
- data/spec/relationship_properties_spec.rb +54 -0
- data/spec/silence.rb +10 -0
- data/spec/spec_helper.rb +101 -0
- data/spec/voip/asterisk/agi_server_spec.rb +473 -0
- data/spec/voip/asterisk/ami/ami_spec.rb +549 -0
- data/spec/voip/asterisk/ami/lexer/ami_fixtures.yml +30 -0
- data/spec/voip/asterisk/ami/lexer/lexer_story +291 -0
- data/spec/voip/asterisk/ami/lexer/lexer_story.rb +241 -0
- data/spec/voip/asterisk/ami/lexer/story_helper.rb +124 -0
- data/spec/voip/asterisk/ami/old_tests.rb +204 -0
- data/spec/voip/asterisk/ami/super_manager/super_manager_story +25 -0
- data/spec/voip/asterisk/ami/super_manager/super_manager_story.rb +15 -0
- data/spec/voip/asterisk/ami/super_manager/super_manager_story_helper.rb +5 -0
- data/spec/voip/asterisk/commands_spec.rb +2179 -0
- data/spec/voip/asterisk/config_file_generators/agents_spec.rb +251 -0
- data/spec/voip/asterisk/config_file_generators/queues_spec.rb +323 -0
- data/spec/voip/asterisk/config_file_generators/voicemail_spec.rb +306 -0
- data/spec/voip/asterisk/config_manager_spec.rb +127 -0
- data/spec/voip/asterisk/menu_command/calculated_match_spec.rb +109 -0
- data/spec/voip/asterisk/menu_command/matchers_spec.rb +97 -0
- data/spec/voip/call_routing_spec.rb +125 -0
- data/spec/voip/dialplan_manager_spec.rb +468 -0
- data/spec/voip/dsl/dialing_dsl_spec.rb +270 -0
- data/spec/voip/dsl/dispatcher_spec.rb +82 -0
- data/spec/voip/dsl/dispatcher_spec_helper.rb +45 -0
- data/spec/voip/dsl/parser_spec.rb +69 -0
- data/spec/voip/freeswitch/basic_connection_manager_spec.rb +39 -0
- data/spec/voip/freeswitch/inbound_connection_manager_spec.rb +39 -0
- data/spec/voip/freeswitch/oes_server_spec.rb +9 -0
- data/spec/voip/numerical_string_spec.rb +61 -0
- data/spec/voip/phone_number_spec.rb +45 -0
- data/theatre-spec/dsl_examples/dynamic_stomp.rb +7 -0
- data/theatre-spec/dsl_examples/simple_before_call.rb +7 -0
- data/theatre-spec/dsl_spec.rb +43 -0
- data/theatre-spec/invocation_spec.rb +167 -0
- data/theatre-spec/namespace_spec.rb +125 -0
- data/theatre-spec/spec_helper.rb +37 -0
- data/theatre-spec/spec_helper_spec.rb +28 -0
- data/theatre-spec/theatre_class_spec.rb +150 -0
- 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 '
|
3
|
+
require 'rspec'
|
4
4
|
rescue LoadError
|
5
|
-
abort
|
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
|
-
|
22
|
-
config.mock_with :
|
15
|
+
RSpec.configure do |config|
|
16
|
+
config.mock_with :rspec
|
23
17
|
config.include ComponentConfigurationSpecHelper
|
24
18
|
end
|
data/lib/adhearsion/version.rb
CHANGED
@@ -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
|