adhearsion 1.0.1 → 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|