hkroger-websocket-rails 0.7.1

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 (120) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +328 -0
  3. data/Gemfile +27 -0
  4. data/MIT-LICENSE +20 -0
  5. data/README.md +237 -0
  6. data/Rakefile +72 -0
  7. data/bin/thin-socketrails +45 -0
  8. data/lib/assets/javascripts/websocket_rails/abstract_connection.js.coffee +45 -0
  9. data/lib/assets/javascripts/websocket_rails/channel.js.coffee +70 -0
  10. data/lib/assets/javascripts/websocket_rails/event.js.coffee +42 -0
  11. data/lib/assets/javascripts/websocket_rails/http_connection.js.coffee +66 -0
  12. data/lib/assets/javascripts/websocket_rails/main.js +6 -0
  13. data/lib/assets/javascripts/websocket_rails/websocket_connection.js.coffee +29 -0
  14. data/lib/assets/javascripts/websocket_rails/websocket_rails.js.coffee +158 -0
  15. data/lib/config.ru +3 -0
  16. data/lib/generators/websocket_rails/install/install_generator.rb +33 -0
  17. data/lib/generators/websocket_rails/install/templates/events.rb +14 -0
  18. data/lib/generators/websocket_rails/install/templates/websocket_rails.rb +63 -0
  19. data/lib/hkroger-websocket-rails.rb +1 -0
  20. data/lib/rails/app/controllers/websocket_rails/delegation_controller.rb +13 -0
  21. data/lib/rails/config/routes.rb +7 -0
  22. data/lib/rails/tasks/websocket_rails.tasks +42 -0
  23. data/lib/spec_helpers/matchers/route_matchers.rb +65 -0
  24. data/lib/spec_helpers/matchers/trigger_matchers.rb +113 -0
  25. data/lib/spec_helpers/spec_helper_event.rb +34 -0
  26. data/lib/websocket-rails.rb +108 -0
  27. data/lib/websocket_rails/base_controller.rb +197 -0
  28. data/lib/websocket_rails/channel.rb +97 -0
  29. data/lib/websocket_rails/channel_manager.rb +55 -0
  30. data/lib/websocket_rails/configuration.rb +169 -0
  31. data/lib/websocket_rails/connection_adapters.rb +195 -0
  32. data/lib/websocket_rails/connection_adapters/http.rb +120 -0
  33. data/lib/websocket_rails/connection_adapters/web_socket.rb +36 -0
  34. data/lib/websocket_rails/connection_manager.rb +119 -0
  35. data/lib/websocket_rails/controller_factory.rb +80 -0
  36. data/lib/websocket_rails/data_store.rb +145 -0
  37. data/lib/websocket_rails/dispatcher.rb +129 -0
  38. data/lib/websocket_rails/engine.rb +26 -0
  39. data/lib/websocket_rails/event.rb +189 -0
  40. data/lib/websocket_rails/event_map.rb +184 -0
  41. data/lib/websocket_rails/event_queue.rb +33 -0
  42. data/lib/websocket_rails/internal_events.rb +37 -0
  43. data/lib/websocket_rails/logging.rb +133 -0
  44. data/lib/websocket_rails/spec_helpers.rb +3 -0
  45. data/lib/websocket_rails/synchronization.rb +182 -0
  46. data/lib/websocket_rails/user_manager.rb +276 -0
  47. data/lib/websocket_rails/version.rb +3 -0
  48. data/spec/dummy/Rakefile +7 -0
  49. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  50. data/spec/dummy/app/controllers/chat_controller.rb +53 -0
  51. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  52. data/spec/dummy/app/models/user.rb +2 -0
  53. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  54. data/spec/dummy/config.ru +4 -0
  55. data/spec/dummy/config/application.rb +45 -0
  56. data/spec/dummy/config/boot.rb +10 -0
  57. data/spec/dummy/config/database.yml +22 -0
  58. data/spec/dummy/config/environment.rb +5 -0
  59. data/spec/dummy/config/environments/development.rb +26 -0
  60. data/spec/dummy/config/environments/production.rb +49 -0
  61. data/spec/dummy/config/environments/test.rb +34 -0
  62. data/spec/dummy/config/events.rb +7 -0
  63. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  64. data/spec/dummy/config/initializers/inflections.rb +10 -0
  65. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  66. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  67. data/spec/dummy/config/initializers/session_store.rb +8 -0
  68. data/spec/dummy/config/locales/en.yml +5 -0
  69. data/spec/dummy/config/routes.rb +58 -0
  70. data/spec/dummy/db/development.sqlite3 +0 -0
  71. data/spec/dummy/db/migrate/20130902222552_create_users.rb +10 -0
  72. data/spec/dummy/db/schema.rb +23 -0
  73. data/spec/dummy/db/test.sqlite3 +0 -0
  74. data/spec/dummy/log/development.log +17 -0
  75. data/spec/dummy/log/production.log +0 -0
  76. data/spec/dummy/log/server.log +0 -0
  77. data/spec/dummy/public/404.html +26 -0
  78. data/spec/dummy/public/422.html +26 -0
  79. data/spec/dummy/public/500.html +26 -0
  80. data/spec/dummy/public/favicon.ico +0 -0
  81. data/spec/dummy/public/javascripts/application.js +2 -0
  82. data/spec/dummy/public/javascripts/controls.js +965 -0
  83. data/spec/dummy/public/javascripts/dragdrop.js +974 -0
  84. data/spec/dummy/public/javascripts/effects.js +1123 -0
  85. data/spec/dummy/public/javascripts/prototype.js +6001 -0
  86. data/spec/dummy/public/javascripts/rails.js +202 -0
  87. data/spec/dummy/script/rails +6 -0
  88. data/spec/integration/connection_manager_spec.rb +135 -0
  89. data/spec/javascripts/support/jasmine.yml +52 -0
  90. data/spec/javascripts/support/jasmine_helper.rb +38 -0
  91. data/spec/javascripts/support/vendor/sinon-1.7.1.js +4343 -0
  92. data/spec/javascripts/websocket_rails/channel_spec.coffee +112 -0
  93. data/spec/javascripts/websocket_rails/event_spec.coffee +69 -0
  94. data/spec/javascripts/websocket_rails/helpers.coffee +6 -0
  95. data/spec/javascripts/websocket_rails/websocket_connection_spec.coffee +158 -0
  96. data/spec/javascripts/websocket_rails/websocket_rails_spec.coffee +274 -0
  97. data/spec/spec_helper.rb +41 -0
  98. data/spec/spec_helpers/matchers/route_matchers_spec.rb +109 -0
  99. data/spec/spec_helpers/matchers/trigger_matchers_spec.rb +247 -0
  100. data/spec/spec_helpers/spec_helper_event_spec.rb +66 -0
  101. data/spec/support/helper_methods.rb +42 -0
  102. data/spec/support/mock_web_socket.rb +41 -0
  103. data/spec/unit/base_controller_spec.rb +74 -0
  104. data/spec/unit/channel_manager_spec.rb +58 -0
  105. data/spec/unit/channel_spec.rb +169 -0
  106. data/spec/unit/connection_adapters/http_spec.rb +88 -0
  107. data/spec/unit/connection_adapters/web_socket_spec.rb +30 -0
  108. data/spec/unit/connection_adapters_spec.rb +259 -0
  109. data/spec/unit/connection_manager_spec.rb +148 -0
  110. data/spec/unit/controller_factory_spec.rb +76 -0
  111. data/spec/unit/data_store_spec.rb +106 -0
  112. data/spec/unit/dispatcher_spec.rb +203 -0
  113. data/spec/unit/event_map_spec.rb +120 -0
  114. data/spec/unit/event_queue_spec.rb +36 -0
  115. data/spec/unit/event_spec.rb +181 -0
  116. data/spec/unit/logging_spec.rb +162 -0
  117. data/spec/unit/synchronization_spec.rb +150 -0
  118. data/spec/unit/target_validator_spec.rb +88 -0
  119. data/spec/unit/user_manager_spec.rb +165 -0
  120. metadata +320 -0
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+ require 'support/mock_web_socket'
3
+
4
+ module WebsocketRails
5
+ module ConnectionAdapters
6
+ describe WebSocket do
7
+
8
+ before do
9
+ @socket = MockWebSocket.new
10
+ Faye::WebSocket.stub(:new).and_return(@socket)
11
+ @adapter = WebSocket.new( mock_request, double('Dispatcher').as_null_object )
12
+ end
13
+
14
+ describe "#send" do
15
+ it "should send the message to the websocket connection" do
16
+ @socket.should_receive(:send).with(:message)
17
+ @adapter.send :message
18
+ end
19
+ end
20
+
21
+ describe "#close!" do
22
+ it "calls #close on the underlying WebSocket connection" do
23
+ @socket.should_receive(:close)
24
+ @adapter.close!
25
+ end
26
+ end
27
+
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,259 @@
1
+ require 'spec_helper'
2
+
3
+ module WebsocketRails
4
+
5
+ class ConnectionAdapters::Test < ConnectionAdapters::Base
6
+ def self.accepts?(env)
7
+ true
8
+ end
9
+ end
10
+
11
+ describe ConnectionAdapters do
12
+
13
+ context ".register" do
14
+ it "should store a reference to the adapter in the adapters array" do
15
+ ConnectionAdapters.register( ConnectionAdapters::Test )
16
+ ConnectionAdapters.adapters.include?( ConnectionAdapters::Test ).should be_true
17
+ end
18
+ end
19
+
20
+ context ".establish_connection" do
21
+ before do
22
+ connection_manager = double(ConnectionManager)
23
+ connection_manager.stub(:connections).and_return({})
24
+ @dispatcher = double(Dispatcher).as_null_object
25
+ @dispatcher.stub(:connection_manager).and_return(connection_manager)
26
+ end
27
+
28
+ it "should return the correct connection adapter instance" do
29
+ adapter = ConnectionAdapters.establish_connection(mock_request, @dispatcher)
30
+ adapter.class.should == ConnectionAdapters::Test
31
+ end
32
+
33
+ end
34
+
35
+ context "ping_timer" do
36
+ it "should set a ping_timer to the default 10 seconds value" do
37
+ adapter = ConnectionAdapters.establish_connection(mock_request, @dispatcher)
38
+ adapter.instance_variable_get(:@ping_timer).interval.should == 10
39
+ end
40
+
41
+ it "should change the ping interval after creation" do
42
+ adapter = ConnectionAdapters.establish_connection(mock_request, @dispatcher)
43
+ adapter.instance_variable_get(:@ping_timer).interval.should == 10
44
+
45
+ adapter.ping_interval = 50
46
+ adapter.instance_variable_get(:@ping_timer).interval.should == 50
47
+ end
48
+
49
+ it "should not set a ping_timer if ping_interval < 1" do
50
+ WebsocketRails.config.default_ping_interval = 0
51
+ adapter = ConnectionAdapters.establish_connection(mock_request, @dispatcher)
52
+ adapter.instance_variable_get(:@ping_timer).should == nil
53
+ end
54
+
55
+ it "should set the ping_timer to the value in the config" do
56
+ WebsocketRails.config.default_ping_interval = 45
57
+ adapter = ConnectionAdapters.establish_connection(mock_request, @dispatcher)
58
+ adapter.instance_variable_get(:@ping_timer).interval.should == 45
59
+ end
60
+ end
61
+
62
+ end
63
+
64
+ module ConnectionAdapters
65
+ describe Base do
66
+ let(:connection_manager) { double(ConnectionManager).as_null_object }
67
+ let(:dispatcher) { double(Dispatcher).as_null_object }
68
+ let(:channel_manager) { double(ChannelManager).as_null_object }
69
+ let(:event) { double(Event).as_null_object }
70
+
71
+ before do
72
+ connection_manager.stub(:connections).and_return({})
73
+ dispatcher.stub(:connection_manager).and_return(connection_manager)
74
+ Event.stub(:new_from_json).and_return(event)
75
+ end
76
+
77
+ subject { Base.new(mock_request, dispatcher) }
78
+
79
+ context "new adapter" do
80
+ it "should register itself in the adapters array when inherited" do
81
+ adapter = Class.new( ConnectionAdapters::Base )
82
+ ConnectionAdapters.adapters.include?( adapter ).should be_true
83
+ end
84
+
85
+ it "should create a new DataStore::Connection instance" do
86
+ subject.data_store.should be_a DataStore::Connection
87
+ end
88
+
89
+ #before do
90
+ # WebsocketRails.config.stub(:user_identifier).and_return(:name)
91
+ # WebsocketRails::DelegationController.any_instance
92
+ # .stub_chain(:current_user, :name)
93
+ # .and_return('Frank')
94
+ # subject
95
+ #end
96
+
97
+ #it "adds itself to the UserManager Hash" do
98
+ # WebsocketRails.users['Frank'].should == subject
99
+ #end
100
+ end
101
+
102
+ describe "#on_open" do
103
+ it "should dispatch an on_open event" do
104
+ on_open_event = double('event').as_null_object
105
+ subject.stub(:send)
106
+ Event.should_receive(:new_on_open).and_return(on_open_event)
107
+ dispatcher.should_receive(:dispatch).with(on_open_event)
108
+ subject.on_open
109
+ end
110
+ end
111
+
112
+ describe "#on_message" do
113
+ it "should forward the data to the dispatcher" do
114
+ dispatcher.should_receive(:dispatch).with(event)
115
+ subject.on_message encoded_message
116
+ end
117
+ end
118
+
119
+ describe "#on_close" do
120
+ it "should dispatch an on_close event" do
121
+ on_close_event = double('event')
122
+ Event.should_receive(:new_on_close).and_return(on_close_event)
123
+ dispatcher.should_receive(:dispatch).with(on_close_event)
124
+ subject.on_close("data")
125
+ end
126
+ end
127
+
128
+ describe "#on_error" do
129
+ it "should dispatch an on_error event" do
130
+ subject.stub(:on_close)
131
+ on_error_event = double('event').as_null_object
132
+ Event.should_receive(:new_on_error).and_return(on_error_event)
133
+ dispatcher.should_receive(:dispatch).with(on_error_event)
134
+ subject.on_error("data")
135
+ end
136
+
137
+ it "should fire the on_close event" do
138
+ data = "test_data"
139
+ subject.should_receive(:on_close).with(data)
140
+ subject.on_error("test_data")
141
+ end
142
+ end
143
+
144
+ describe "#send_message" do
145
+ before do
146
+ Event.any_instance.stub(:trigger)
147
+ end
148
+ after do
149
+ subject.send_message :message, "some_data"
150
+ end
151
+
152
+ it "creates and triggers a new event" do
153
+ Event.any_instance.should_receive(:trigger)
154
+ end
155
+
156
+ it "sets it's user identifier on the event" do
157
+ subject.stub(:user_identifier).and_return(:some_name_or_id)
158
+ Event.should_receive(:new) do |name, options|
159
+ options[:user_id].should == :some_name_or_id
160
+ end.and_call_original
161
+ end
162
+
163
+ it "sets the connection property of the event correctly" do
164
+ subject.stub(:user_identifier).and_return(:some_name_or_id)
165
+ Event.should_receive(:new) do |name, options|
166
+ options[:connection].should == subject
167
+ end.and_call_original
168
+ end
169
+ end
170
+
171
+ describe "#send" do
172
+ it "should raise a NotImplementedError exception" do
173
+ expect { subject.send :message }.to raise_exception(NotImplementedError)
174
+ end
175
+ end
176
+
177
+ describe "#user_connection?" do
178
+ context "when a user is signed in" do
179
+ before do
180
+ subject.stub(:user_identifier).and_return("Jimbo Jones")
181
+ end
182
+
183
+ it "returns true" do
184
+ subject.user_connection?.should == true
185
+ end
186
+ end
187
+
188
+ context "when a user is signed out" do
189
+ before do
190
+ subject.stub(:user_identifier).and_return(nil)
191
+ end
192
+
193
+ it "returns true" do
194
+ subject.user_connection?.should == false
195
+ end
196
+ end
197
+ end
198
+
199
+ describe "#user" do
200
+ it "provides access to the current_user object" do
201
+ user = double('User')
202
+ subject.stub(:user_identifier).and_return true
203
+ subject.stub_chain(:controller_delegate, :current_user).and_return user
204
+ subject.user.should == user
205
+ end
206
+ end
207
+
208
+ describe "#enqueue" do
209
+ it "should add the event to the queue" do
210
+ subject.enqueue 'event'
211
+ subject.queue.queue.should == ['event']
212
+ end
213
+ end
214
+
215
+ describe "#flush" do
216
+ before do
217
+ event = Event.new(:queued_event, data: 'test')
218
+ 2.times { subject.enqueue event }
219
+ end
220
+
221
+ it "should serialize all events into one array" do
222
+ serialized_array = <<-EOF.strip_heredoc
223
+ [["queued_event",{"id":null,"channel":null,"user_id":null,"data":"test","success":null,"result":null,"token":null,"server_token":null}],
224
+ ["queued_event",{"id":null,"channel":null,"user_id":null,"data":"test","success":null,"result":null,"token":null,"server_token":null}]]
225
+ EOF
226
+
227
+ subject.should_receive(:send).with(serialized_array.gsub(/\n/,'').strip)
228
+ subject.flush
229
+ end
230
+ end
231
+
232
+ describe "#trigger" do
233
+ it "passes a serialized event to the connections #send method" do
234
+ event.stub(:serialize).and_return('test')
235
+ subject.should_receive(:send).with "[test]"
236
+ subject.trigger event
237
+ end
238
+ end
239
+
240
+ describe "#close_connection" do
241
+ before do
242
+ subject.stub(:user_identifier).and_return(1)
243
+ @connection_manager = double('connection_manager').as_null_object
244
+ subject.stub_chain(:dispatcher, :connection_manager).and_return(@connection_manager)
245
+ end
246
+
247
+ it "calls delegates to the conection manager" do
248
+ @connection_manager.should_receive(:close_connection).with(subject)
249
+ subject.__send__(:close_connection)
250
+ end
251
+
252
+ it "deletes it's data_store" do
253
+ subject.data_store.should_receive(:destroy!)
254
+ subject.__send__(:close_connection)
255
+ end
256
+ end
257
+ end
258
+ end
259
+ end
@@ -0,0 +1,148 @@
1
+ require 'spec_helper'
2
+
3
+ module WebsocketRails
4
+ describe ConnectionManager do
5
+ include Rack::Test::Methods
6
+
7
+ def app
8
+ @app ||= ConnectionManager.new
9
+ end
10
+
11
+ def open_connection
12
+ subject.call(env)
13
+ end
14
+
15
+ let(:connections) { subject.connections }
16
+ let(:dispatcher) { subject.dispatcher }
17
+
18
+ before(:each) do
19
+ ConnectionAdapters::Base.any_instance.stub(:send)
20
+ @mock_socket = ConnectionAdapters::Base.new(mock_request, dispatcher)
21
+ ConnectionAdapters.stub(:establish_connection).and_return(@mock_socket)
22
+ end
23
+
24
+ describe "#initialize" do
25
+ it "should create an empty connections hash" do
26
+ subject.connections.should be_a Hash
27
+ end
28
+
29
+ it "should create a new dispatcher instance" do
30
+ subject.dispatcher.should be_a Dispatcher
31
+ end
32
+ end
33
+
34
+ context "new connections" do
35
+ it "should add one to the total connection count" do
36
+ expect { open_connection }.to change { connections.count }.by(1)
37
+ end
38
+
39
+ it "should store the new connection in the @connections Hash" do
40
+ open_connection
41
+ connections[@mock_socket.id].should == @mock_socket
42
+ end
43
+
44
+ it "should return an Async Rack response" do
45
+ open_connection.should == [ -1, {}, [] ]
46
+ end
47
+
48
+ before do
49
+ SecureRandom.stub(:hex).and_return(1, 2)
50
+ end
51
+
52
+ it "gives the new connection a unique ID" do
53
+ @mock_socket.should_receive(:id=).with(1)
54
+ open_connection
55
+ @mock_socket.should_receive(:id=).with(2)
56
+ open_connection
57
+ end
58
+
59
+ context "user connections" do
60
+ before do
61
+ @mock_socket.stub(:user_connection?).and_return true
62
+ @mock_socket.stub(:user_identifier).and_return "El Jefe"
63
+ open_connection
64
+ end
65
+
66
+ it "stores the connection in the UserManager" do
67
+ WebsocketRails.users["El Jefe"].connections.first.should == @mock_socket
68
+ end
69
+ end
70
+ end
71
+
72
+ context "new POST event" do
73
+ before(:each) do
74
+ @mock_http = ConnectionAdapters::Http.new(mock_request, dispatcher)
75
+ @mock_http.id = 'is_i_as_string'
76
+ app.connections[@mock_http.id] = @mock_http
77
+ end
78
+
79
+ it "should receive the new event for the correct connection" do
80
+ @mock_http.should_receive(:on_message).with(encoded_message)
81
+ post '/websocket', {:client_id => @mock_http.id, :data => encoded_message}
82
+ end
83
+ end
84
+
85
+ context "open connections" do
86
+ before(:each) do
87
+ ConnectionAdapters.stub(:establish_connection).and_return(@mock_socket, ConnectionAdapters::Base.new(mock_request, dispatcher))
88
+ 4.times { open_connection }
89
+ end
90
+
91
+ context "when receiving a new event" do
92
+ before(:each) { open_connection }
93
+
94
+ it "should dispatch the appropriate event through the Dispatcher" do
95
+ mock_event = ["new_message",{:data =>"data"}].to_json
96
+ dispatcher.should_receive(:dispatch) do |event|
97
+ event.name.should == :new_message
98
+ event.data.should == "data"
99
+ event.connection.should == @mock_socket
100
+ end
101
+ @mock_socket.on_message(mock_event)
102
+ end
103
+ end
104
+
105
+ context "when closing" do
106
+ it "should remove the connection object from the @connections array" do
107
+ @mock_socket.on_close
108
+ connections.has_key?(@mock_socket.id).should be_false
109
+ end
110
+
111
+ it "should decrement the connection count by one" do
112
+ expect { @mock_socket.on_close }.to change { connections.count }.by(-1)
113
+ end
114
+
115
+ it "should dispatch the :client_disconnected event" do
116
+ dispatcher.should_receive(:dispatch) do |event|
117
+ event.name.should == :client_disconnected
118
+ event.connection.should == @mock_socket
119
+ end
120
+ @mock_socket.on_close
121
+ end
122
+
123
+ context "user connections" do
124
+ before do
125
+ @mock_socket.stub(:user_connection?).and_return true
126
+ @mock_socket.stub(:user_identifier).and_return "El Jefe"
127
+ end
128
+
129
+ it "deletes the connection from the UserManager" do
130
+ @mock_socket.on_close
131
+ WebsocketRails.users["El Jefe"].class.should == UserManager::MissingConnection
132
+ end
133
+ end
134
+ end
135
+
136
+ end
137
+
138
+ context "invalid connections" do
139
+ before(:each) do
140
+ ConnectionAdapters.stub(:establish_connection).and_raise(InvalidConnectionError)
141
+ end
142
+
143
+ it "should return a 400 bad request error code" do
144
+ open_connection.first.should == 400
145
+ end
146
+ end
147
+ end
148
+ end
@@ -0,0 +1,76 @@
1
+ require "spec_helper"
2
+
3
+ module WebsocketRails
4
+ describe ControllerFactory do
5
+
6
+ class TestController < BaseController
7
+ attr_reader :_dispatcher, :_event
8
+
9
+ def initialize_session
10
+ true
11
+ end
12
+ end
13
+
14
+ let(:dispatcher) { double('dispatcher') }
15
+ let(:connection) { double('connection') }
16
+ let(:event) { double('event') }
17
+
18
+ subject { ControllerFactory.new(dispatcher) }
19
+
20
+ before do
21
+ connection.stub(:id).and_return(1)
22
+ event.stub(:connection).and_return(connection)
23
+ end
24
+
25
+ it "stores a reference to the dispatcher" do
26
+ subject.dispatcher.should == dispatcher
27
+ end
28
+
29
+ it "maintains a hash of controller data stores" do
30
+ subject.controller_stores.should be_a Hash
31
+ end
32
+
33
+ describe "#new_for_event" do
34
+
35
+ context "when Rails is defined and env is set to development" do
36
+
37
+ it "creates and returns a controller instance of the InternalController" do
38
+ rails_env = double(:rails_env)
39
+ Rails.stub(:env).and_return rails_env
40
+ rails_env.stub(:development?).and_return true
41
+ controller = subject.new_for_event(event, InternalController, 'some_method')
42
+ controller.class.should == InternalController
43
+ end
44
+
45
+ end
46
+
47
+ it "creates and returns a new controller instance" do
48
+ controller = subject.new_for_event(event, TestController, 'some_method')
49
+ controller.class.should == TestController
50
+ end
51
+
52
+ it "initializes the controller with the correct data_store" do
53
+ store = double('data_store')
54
+ subject.controller_stores[TestController] = store
55
+ controller = subject.new_for_event(event, TestController, 'some_method')
56
+ controller.controller_store.should == store
57
+ end
58
+
59
+ it "initializes the controller with the correct event" do
60
+ controller = subject.new_for_event(event, TestController, 'some_method')
61
+ controller.event.should == event
62
+ end
63
+
64
+ it "initializes the controller with the correct dispatcher" do
65
+ controller = subject.new_for_event(event, TestController, 'some_method')
66
+ controller._dispatcher.should == dispatcher
67
+ end
68
+
69
+ it "calls #initialize_session on the controller only once" do
70
+ TestController.any_instance.should_receive(:initialize_session).once
71
+ 3.times { subject.new_for_event(event, TestController, 'some_method') }
72
+ end
73
+ end
74
+
75
+ end
76
+ end