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
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'adhearsion/voip/freeswitch/basic_connection_manager'
|
3
|
+
|
4
|
+
include Adhearsion::VoIP::FreeSwitch
|
5
|
+
|
6
|
+
describe "FreeSwitch BasicConnectionManager" do
|
7
|
+
attr_reader :manager, :io
|
8
|
+
before(:each) do
|
9
|
+
@io = StringIO.new
|
10
|
+
@manager = BasicConnectionManager.new io
|
11
|
+
end
|
12
|
+
|
13
|
+
it "<<() should add two newlines" do
|
14
|
+
manager << "foobar"
|
15
|
+
io.string.should == "foobar\n\n"
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "FreeSwitch BasicConnectionManager's header parser" do
|
21
|
+
it "YAML-like headers are read properly" do
|
22
|
+
header = {
|
23
|
+
"Foo-Bar" => "bar",
|
24
|
+
"Qaz-Monkey-Charlie-Zebra" => "qwerty"
|
25
|
+
}
|
26
|
+
|
27
|
+
string_header = header.inject("") do |string, (key, value)|
|
28
|
+
string + "#{key}: #{value}\n"
|
29
|
+
end
|
30
|
+
|
31
|
+
string_header << "\n"
|
32
|
+
|
33
|
+
manager = BasicConnectionManager.new StringIO.new(string_header)
|
34
|
+
manager.get_raw_header.should == string_header.strip
|
35
|
+
|
36
|
+
manager = BasicConnectionManager.new StringIO.new(string_header)
|
37
|
+
manager.get_header.should == header
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'adhearsion/voip/freeswitch/inbound_connection_manager'
|
3
|
+
include Adhearsion::VoIP::FreeSwitch
|
4
|
+
|
5
|
+
describe "A FreeSwitch InboundConnectionManager" do
|
6
|
+
|
7
|
+
it "authenticatating with the given password" do
|
8
|
+
manager = InboundConnectionManager.new io_mock
|
9
|
+
manager.login password
|
10
|
+
end
|
11
|
+
|
12
|
+
it "a hash is accepted when creating a new InboundConnectionManager" do
|
13
|
+
host, port = "myhost.mydomain", 31337
|
14
|
+
|
15
|
+
flexmock(TCPSocket).should_receive(:new).once.with(host, port).and_return io_mock
|
16
|
+
|
17
|
+
InboundConnectionManager.new :host => host, :port => port, :pass => password
|
18
|
+
end
|
19
|
+
|
20
|
+
it "an IO is accepted when creating a new InboundConnectionManager"
|
21
|
+
|
22
|
+
private
|
23
|
+
def io_mock
|
24
|
+
@io_mock ||=
|
25
|
+
begin
|
26
|
+
io_mock = StringIO.new
|
27
|
+
flexmock(io_mock) do |io|
|
28
|
+
io.should_receive(:write).with("auth #{password}\n\n")
|
29
|
+
io.should_receive(:gets).and_return "connection: kthnx\n",
|
30
|
+
"\n", "login: +OK\n", "\n"
|
31
|
+
end
|
32
|
+
io_mock
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def password
|
37
|
+
"supersecret"
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require File.dirname(__FILE__) + "/../dsl/dispatcher_spec_helper"
|
3
|
+
require 'adhearsion/voip/freeswitch/oes_server'
|
4
|
+
|
5
|
+
|
6
|
+
describe "Adhearsion::VoIP::FreeSwitch::OesServer::OesDispatcher" do
|
7
|
+
include StandardDispatcherBehavior
|
8
|
+
before(:each) { @dispatcher_class = Adhearsion::VoIP::FreeSwitch::OesServer::OesDispatcher }
|
9
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'adhearsion/voip/dsl/numerical_string'
|
4
|
+
require 'adhearsion/voip/constants'
|
5
|
+
|
6
|
+
describe "A NumericalString" do
|
7
|
+
# FIXME: This test is fundamentally broken in Ruby 1.9.
|
8
|
+
# See https://adhearsion.lighthouseapp.com/projects/5871/tickets/127-ruby-19-and-numericalstring-comparisons-in-case-statements
|
9
|
+
# The suggested workaround is to cast the object to a string:
|
10
|
+
# case numerical_string_object.to_s
|
11
|
+
# when "0987" then ...
|
12
|
+
# end
|
13
|
+
# it "should appear to be behave like a Fixnum in a case statement" do
|
14
|
+
# case numerical_string_for("123")
|
15
|
+
# when 123 then true
|
16
|
+
# else false
|
17
|
+
# end.should be true
|
18
|
+
#
|
19
|
+
# case numerical_string_for("0987")
|
20
|
+
# when 987 then true
|
21
|
+
# else false
|
22
|
+
# end.should be true
|
23
|
+
# end
|
24
|
+
|
25
|
+
it "should appear to behave like a String in a case statement" do
|
26
|
+
numerical_string_for("123").should === "123"
|
27
|
+
numerical_string_for("0987").should === "0987"
|
28
|
+
end
|
29
|
+
|
30
|
+
it "when compared against a Range that contains the numeric equivalent, the NumericalString is seen as a member" do
|
31
|
+
(100..200).should === numerical_string_for("150")
|
32
|
+
(100..200).should === numerical_string_for("0150")
|
33
|
+
(100..200).should_not === numerical_string_for("1000000")
|
34
|
+
end
|
35
|
+
|
36
|
+
it "comparing against a regular expression works" do
|
37
|
+
%r|^\d+$|.should === numerical_string_for("027316287")
|
38
|
+
end
|
39
|
+
|
40
|
+
it "checking if a string representation of a number starts with a leading zero" do
|
41
|
+
with_leading_zeros = %w(01 01234 01.23 01.2)
|
42
|
+
without_leading_zeros = %w(1 1.2 0 0.0)
|
43
|
+
|
44
|
+
with_leading_zeros.each do |number|
|
45
|
+
numerical_string.starts_with_leading_zero?(number).should_not be false
|
46
|
+
end
|
47
|
+
|
48
|
+
without_leading_zeros.each do |number|
|
49
|
+
numerical_string.starts_with_leading_zero?(number).should_not be true
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
def numerical_string
|
55
|
+
Adhearsion::VoIP::DSL::NumericalString
|
56
|
+
end
|
57
|
+
|
58
|
+
def numerical_string_for(string)
|
59
|
+
numerical_string.new(string)
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'adhearsion/voip/constants'
|
3
|
+
require 'adhearsion/voip/dsl/numerical_string'
|
4
|
+
|
5
|
+
|
6
|
+
# Use cases...
|
7
|
+
# case extension
|
8
|
+
# when US_NUMBER
|
9
|
+
# when (100..200)
|
10
|
+
# when _('12Z')
|
11
|
+
# when 123
|
12
|
+
# when "123"
|
13
|
+
# end
|
14
|
+
|
15
|
+
def should_be_nil_or_false(arg)
|
16
|
+
[nil, false].include?(arg).should == true
|
17
|
+
end
|
18
|
+
|
19
|
+
def should_not_be_nil_or_false(arg)
|
20
|
+
[nil, false].include?(arg).should == false
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "A PhoneNumber" do
|
24
|
+
|
25
|
+
it "should have an ISN pattern-matching method" do
|
26
|
+
should_be_nil_or_false Adhearsion::VoIP::DSL::PhoneNumber.new("0115544332211").isn?
|
27
|
+
should_not_be_nil_or_false Adhearsion::VoIP::DSL::PhoneNumber.new("1*548").isn?
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should have a US local number pattern-matching method" do
|
31
|
+
should_be_nil_or_false Adhearsion::VoIP::DSL::PhoneNumber.new("18887776665555").us_local_number?
|
32
|
+
should_be_nil_or_false Adhearsion::VoIP::DSL::PhoneNumber.new("18887776665555").us_national_number?
|
33
|
+
|
34
|
+
should_be_nil_or_false Adhearsion::VoIP::DSL::PhoneNumber.new("8887776665555").us_local_number?
|
35
|
+
should_be_nil_or_false Adhearsion::VoIP::DSL::PhoneNumber.new("8887776665555").us_national_number?
|
36
|
+
|
37
|
+
should_not_be_nil_or_false Adhearsion::VoIP::DSL::PhoneNumber.new("4445555").us_local_number?
|
38
|
+
should_be_nil_or_false Adhearsion::VoIP::DSL::PhoneNumber.new("4445555").us_national_number?
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should convert from vanity numbers properly" do
|
42
|
+
Adhearsion::VoIP::DSL::PhoneNumber.from_vanity("1-800-FUDGEME").should == "18003834363"
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "CallbackDefinitionContainer" do
|
4
|
+
|
5
|
+
it "should successfully load the :simple_before_call example" do
|
6
|
+
example = Example.new(:simple_before_call)
|
7
|
+
theatre = Theatre::Theatre.new
|
8
|
+
example.register_namespaces_on theatre
|
9
|
+
|
10
|
+
flexmock(theatre.namespace_manager).should_receive(:register_callback_at_namespace).
|
11
|
+
with([:asterisk, :before_call], Proc).once
|
12
|
+
|
13
|
+
loader = Theatre::CallbackDefinitionLoader.new(theatre)
|
14
|
+
loader.load_events_file example.file
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should let you override the recorder method name" do
|
18
|
+
theatre = Theatre::Theatre.new
|
19
|
+
theatre.namespace_manager.register_namespace_name "/foo/bar/qaz"
|
20
|
+
flexmock(theatre.namespace_manager).should_receive(:register_callback_at_namespace).
|
21
|
+
with([:foo, :bar, :qaz], Proc).once
|
22
|
+
|
23
|
+
loader = Theatre::CallbackDefinitionLoader.new(theatre, :roflcopter)
|
24
|
+
loader.roflcopter.foo.bar.qaz.each {}
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
# High level specs to test the entire library.
|
30
|
+
|
31
|
+
describe "Misuses of the Theatre" do
|
32
|
+
|
33
|
+
it "should not allow callbacks to be registered for namespaces which have not been registered" do
|
34
|
+
theatre = Theatre::Theatre.new
|
35
|
+
example = Example.new(:simple_before_call)
|
36
|
+
|
37
|
+
loader = Theatre::CallbackDefinitionLoader.new(theatre)
|
38
|
+
lambda do
|
39
|
+
loader.events.foo.each {}
|
40
|
+
end.should raise_error(Theatre::NamespaceNotFound)
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
@@ -0,0 +1,167 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
GUID_REGEXP = /^[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}$/i
|
4
|
+
|
5
|
+
module InvocationTestHelper
|
6
|
+
def new_invocation(payload=@payload)
|
7
|
+
Theatre::Invocation.new(@namespace, @block, @payload)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "The lifecycle of an Invocation" do
|
12
|
+
|
13
|
+
include InvocationTestHelper
|
14
|
+
|
15
|
+
before :all do
|
16
|
+
@block = lambda {}
|
17
|
+
@payload = 123
|
18
|
+
@namespace = "/some/namespace"
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should have an initial state of :new" do
|
22
|
+
new_invocation.current_state.should eql(:new)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should not have a @queued_time until state becomes :queued" do
|
26
|
+
invocation = new_invocation
|
27
|
+
invocation.queued_time.should eql(nil)
|
28
|
+
invocation.queued
|
29
|
+
invocation.queued_time.should be_instance_of(Time)
|
30
|
+
invocation.current_state.should eql(:queued)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should have a valid guid when instantiated" do
|
34
|
+
new_invocation.unique_id.should =~ GUID_REGEXP
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should execute the callback when moving to the 'start' state" do
|
38
|
+
flexmock(@block).should_receive(:call).once
|
39
|
+
invocation = new_invocation
|
40
|
+
invocation.queued
|
41
|
+
invocation.start
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "Using Invocations that've been ran through the Theatre" do
|
47
|
+
|
48
|
+
it "should pass the payload to the callback" do
|
49
|
+
destined_payload = [:i_feel_so_pretty, :OH, :SO, :PRETTY!]
|
50
|
+
expecting_callback = lambda do |payload|
|
51
|
+
payload.should equal(destined_payload)
|
52
|
+
end
|
53
|
+
invocation = Theatre::Invocation.new("/namespace/whatever", expecting_callback, destined_payload)
|
54
|
+
invocation.queued
|
55
|
+
invocation.start
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should have a status of :error if an exception was raised and set the #error property" do
|
59
|
+
errorful_callback = lambda { raise ArgumentError, "this error is intentional" } # Simulate logic error
|
60
|
+
invocation = Theatre::Invocation.new("/namespace/whatever", errorful_callback)
|
61
|
+
invocation.queued
|
62
|
+
invocation.start
|
63
|
+
invocation.current_state.should equal(:error)
|
64
|
+
invocation.should be_error
|
65
|
+
invocation.error.should be_instance_of(ArgumentError)
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should have a status of :success if no expection was raised" do
|
69
|
+
callback = lambda { "No errors raised here!" }
|
70
|
+
invocation = Theatre::Invocation.new("/namespace/whatever", callback)
|
71
|
+
invocation.queued
|
72
|
+
invocation.start
|
73
|
+
invocation.current_state.should equal(:success)
|
74
|
+
invocation.should be_success
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should set the #returned_value property to the returned value callback when a payload was given" do
|
78
|
+
doubler = lambda { |num| num * 2 }
|
79
|
+
invocation = Theatre::Invocation.new('/foo/bar', doubler, 5)
|
80
|
+
invocation.queued
|
81
|
+
invocation.start
|
82
|
+
invocation.returned_value.should equal(10)
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should set the #returned_value property to the returned value callback when a payload was NOT given" do
|
86
|
+
doubler = lambda { :ohai }
|
87
|
+
invocation = Theatre::Invocation.new('/foo/bar', doubler)
|
88
|
+
invocation.queued
|
89
|
+
invocation.start
|
90
|
+
invocation.returned_value.should equal(:ohai)
|
91
|
+
end
|
92
|
+
|
93
|
+
it "should set the #finished_time property when a success was encountered" do
|
94
|
+
block = lambda {}
|
95
|
+
invocation = Theatre::Invocation.new('/foo/bar', block)
|
96
|
+
invocation.queued
|
97
|
+
|
98
|
+
now = Time.now
|
99
|
+
flexmock(Time).should_receive(:now).twice.and_return now
|
100
|
+
|
101
|
+
invocation.start
|
102
|
+
invocation.should be_success
|
103
|
+
end
|
104
|
+
|
105
|
+
it "should set the #finished_time property when a failure was encountered" do
|
106
|
+
block = lambda { raise LocalJumpError }
|
107
|
+
invocation = Theatre::Invocation.new('/foo/bar', block)
|
108
|
+
invocation.queued
|
109
|
+
|
110
|
+
now = Time.now
|
111
|
+
flexmock(Time).should_receive(:now).twice.and_return now
|
112
|
+
|
113
|
+
invocation.start
|
114
|
+
invocation.should be_error
|
115
|
+
end
|
116
|
+
|
117
|
+
it "should set the #started_time property after starting" do
|
118
|
+
invocation = Theatre::Invocation.new('/foo/bar', lambda { sleep 0.01 } )
|
119
|
+
invocation.queued
|
120
|
+
invocation.started_time.should be_nil
|
121
|
+
invocation.start
|
122
|
+
invocation.started_time.should be_kind_of(Time)
|
123
|
+
end
|
124
|
+
|
125
|
+
it "should properly calculate #execution_duration" do
|
126
|
+
time_ago_difference = 60 * 5 # Five minutes
|
127
|
+
time_now = Time.now
|
128
|
+
time_ago = time_now - time_ago_difference
|
129
|
+
|
130
|
+
invocation = Theatre::Invocation.new('/foo/bar', lambda {} )
|
131
|
+
invocation.queued
|
132
|
+
invocation.start
|
133
|
+
|
134
|
+
invocation.send(:instance_variable_set, :@started_time, time_ago)
|
135
|
+
invocation.send(:instance_variable_set, :@finished_time, time_now)
|
136
|
+
|
137
|
+
invocation.execution_duration.should be_close(time_ago_difference.to_f, 0.01)
|
138
|
+
end
|
139
|
+
|
140
|
+
it "should return the set value of returned_value when one has been set to a non-nil value" do
|
141
|
+
return_nil = lambda { 123 }
|
142
|
+
invocation = Theatre::Invocation.new("/namespace/whatever", return_nil)
|
143
|
+
invocation.queued
|
144
|
+
invocation.start
|
145
|
+
invocation.returned_value.should eql(123)
|
146
|
+
end
|
147
|
+
|
148
|
+
it "should return nil for returned_value when it has been set to nil" do
|
149
|
+
return_nil = lambda { nil }
|
150
|
+
invocation = Theatre::Invocation.new("/namespace/whatever", return_nil)
|
151
|
+
invocation.queued
|
152
|
+
invocation.start
|
153
|
+
invocation.returned_value.should eql(nil)
|
154
|
+
end
|
155
|
+
|
156
|
+
it "waiting on an Invocation should execute properly" do
|
157
|
+
wait_on_invocation = lambda { 123 }
|
158
|
+
invocation = Theatre::Invocation.new("/namespace/whatever", wait_on_invocation)
|
159
|
+
Thread.new do
|
160
|
+
invocation.queued
|
161
|
+
invocation.start
|
162
|
+
end
|
163
|
+
invocation.wait.should eql(123)
|
164
|
+
invocation.success?.should eql(true)
|
165
|
+
end
|
166
|
+
|
167
|
+
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module NamespaceHelper
|
4
|
+
class BeValidNamespace
|
5
|
+
|
6
|
+
def matches?(target)
|
7
|
+
@target = target
|
8
|
+
Theatre::ActorNamespaceManager.valid_namespace_path? target
|
9
|
+
end
|
10
|
+
|
11
|
+
def failure_message
|
12
|
+
"expected #{@target.inspect} to be a valid namespace"
|
13
|
+
end
|
14
|
+
|
15
|
+
def negative_failure_message
|
16
|
+
"expected #{@target.inspect} not to be a valid namespace"
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
def be_valid_actor_event_namespace
|
22
|
+
BeValidNamespace.new
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "ActorNamespaceManager" do
|
28
|
+
|
29
|
+
it "should make a registered namespace findable once registered" do
|
30
|
+
nm = Theatre::ActorNamespaceManager.new
|
31
|
+
nm.register_namespace_name "/foo/bar/qaz"
|
32
|
+
nm.search_for_namespace("/foo/bar/qaz").should be_kind_of(Theatre::ActorNamespaceManager::NamespaceNode)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should return the new namespace when registering it" do
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
it "#search_for_namespace should raise a NamespaceNotFound exception if a namespace one level deep was not found" do
|
40
|
+
nm = Theatre::ActorNamespaceManager.new
|
41
|
+
lambda do
|
42
|
+
nm.search_for_namespace "/foo"
|
43
|
+
end.should raise_error(Theatre::NamespaceNotFound)
|
44
|
+
end
|
45
|
+
|
46
|
+
it "#search_for_namespace should raise a NamespaceNotFound exception if a namespace two levels deep was not found" do
|
47
|
+
nm = Theatre::ActorNamespaceManager.new
|
48
|
+
lambda do
|
49
|
+
nm.search_for_namespace "/foo/bar"
|
50
|
+
end.should raise_error(Theatre::NamespaceNotFound)
|
51
|
+
end
|
52
|
+
|
53
|
+
describe '::normalize_path_to_array' do
|
54
|
+
it "should split a standard path properly" do
|
55
|
+
Theatre::ActorNamespaceManager.normalize_path_to_array("/foo/bar/qaz").should == [:foo, :bar, :qaz]
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should split out Array()'d form of a String path properly" do
|
59
|
+
Theatre::ActorNamespaceManager.normalize_path_to_array(["/jay/thomas/phillips"]).should == [:jay,:thomas,:phillips]
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
describe "NamespaceNode" do
|
66
|
+
|
67
|
+
it "when registering a new namespace, the new NamespaceNode should be returned" do
|
68
|
+
node = Theatre::ActorNamespaceManager::NamespaceNode.new "foobar"
|
69
|
+
node.register_namespace_name("foobar").should be_instance_of(Theatre::ActorNamespaceManager::NamespaceNode)
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should not blow away an existing callback when registering a new one with the same name" do
|
73
|
+
name = "blah"
|
74
|
+
node = Theatre::ActorNamespaceManager::NamespaceNode.new name
|
75
|
+
node.register_namespace_name name
|
76
|
+
before = node.child_named(name)
|
77
|
+
before.should be_instance_of(Theatre::ActorNamespaceManager::NamespaceNode)
|
78
|
+
node.register_namespace_name name
|
79
|
+
before.should eql(node.child_named(name))
|
80
|
+
end
|
81
|
+
|
82
|
+
describe '#register_namespace_name' do
|
83
|
+
it "should return the NamespaceNode" do
|
84
|
+
Theatre::ActorNamespaceManager::NamespaceNode.new("foo").register_namespace_name("bar").should \
|
85
|
+
be_instance_of(Theatre::ActorNamespaceManager::NamespaceNode)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
|
91
|
+
describe "Valid namespace segments" do
|
92
|
+
|
93
|
+
include NamespaceHelper
|
94
|
+
|
95
|
+
describe "a valid namespace path" do
|
96
|
+
|
97
|
+
it "should require a namespace path start with a /" do
|
98
|
+
"/foo". should be_valid_actor_event_namespace
|
99
|
+
"foo". should_not be_valid_actor_event_namespace
|
100
|
+
"foo/bar".should_not be_valid_actor_event_namespace
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should allow multiple namespace segments" do
|
104
|
+
"/foo_foo/bar".should be_valid_actor_event_namespace
|
105
|
+
end
|
106
|
+
|
107
|
+
it "should not allow a trailing forward slash" do
|
108
|
+
"/foo/bar/".should_not be_valid_actor_event_namespace
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should not allow backslashes" do
|
112
|
+
'\foo'.should_not be_valid_actor_event_namespace
|
113
|
+
'\foo\bar'.should_not be_valid_actor_event_namespace
|
114
|
+
'foo\bar'.should_not be_valid_actor_event_namespace
|
115
|
+
'\bar\\'.should_not be_valid_actor_event_namespace
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should not allow weird characters" do
|
119
|
+
%w[ ! @ # $ % ^ & * ( ) { } | ' : ? > < - = ].each do |bad_character|
|
120
|
+
"/foo#{bad_character}foo/bar".should_not be_valid_actor_event_namespace
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
125
|
+
end
|