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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +328 -0
- data/Gemfile +27 -0
- data/MIT-LICENSE +20 -0
- data/README.md +237 -0
- data/Rakefile +72 -0
- data/bin/thin-socketrails +45 -0
- data/lib/assets/javascripts/websocket_rails/abstract_connection.js.coffee +45 -0
- data/lib/assets/javascripts/websocket_rails/channel.js.coffee +70 -0
- data/lib/assets/javascripts/websocket_rails/event.js.coffee +42 -0
- data/lib/assets/javascripts/websocket_rails/http_connection.js.coffee +66 -0
- data/lib/assets/javascripts/websocket_rails/main.js +6 -0
- data/lib/assets/javascripts/websocket_rails/websocket_connection.js.coffee +29 -0
- data/lib/assets/javascripts/websocket_rails/websocket_rails.js.coffee +158 -0
- data/lib/config.ru +3 -0
- data/lib/generators/websocket_rails/install/install_generator.rb +33 -0
- data/lib/generators/websocket_rails/install/templates/events.rb +14 -0
- data/lib/generators/websocket_rails/install/templates/websocket_rails.rb +63 -0
- data/lib/hkroger-websocket-rails.rb +1 -0
- data/lib/rails/app/controllers/websocket_rails/delegation_controller.rb +13 -0
- data/lib/rails/config/routes.rb +7 -0
- data/lib/rails/tasks/websocket_rails.tasks +42 -0
- data/lib/spec_helpers/matchers/route_matchers.rb +65 -0
- data/lib/spec_helpers/matchers/trigger_matchers.rb +113 -0
- data/lib/spec_helpers/spec_helper_event.rb +34 -0
- data/lib/websocket-rails.rb +108 -0
- data/lib/websocket_rails/base_controller.rb +197 -0
- data/lib/websocket_rails/channel.rb +97 -0
- data/lib/websocket_rails/channel_manager.rb +55 -0
- data/lib/websocket_rails/configuration.rb +169 -0
- data/lib/websocket_rails/connection_adapters.rb +195 -0
- data/lib/websocket_rails/connection_adapters/http.rb +120 -0
- data/lib/websocket_rails/connection_adapters/web_socket.rb +36 -0
- data/lib/websocket_rails/connection_manager.rb +119 -0
- data/lib/websocket_rails/controller_factory.rb +80 -0
- data/lib/websocket_rails/data_store.rb +145 -0
- data/lib/websocket_rails/dispatcher.rb +129 -0
- data/lib/websocket_rails/engine.rb +26 -0
- data/lib/websocket_rails/event.rb +189 -0
- data/lib/websocket_rails/event_map.rb +184 -0
- data/lib/websocket_rails/event_queue.rb +33 -0
- data/lib/websocket_rails/internal_events.rb +37 -0
- data/lib/websocket_rails/logging.rb +133 -0
- data/lib/websocket_rails/spec_helpers.rb +3 -0
- data/lib/websocket_rails/synchronization.rb +182 -0
- data/lib/websocket_rails/user_manager.rb +276 -0
- data/lib/websocket_rails/version.rb +3 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/controllers/chat_controller.rb +53 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/models/user.rb +2 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +45 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml +22 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +26 -0
- data/spec/dummy/config/environments/production.rb +49 -0
- data/spec/dummy/config/environments/test.rb +34 -0
- data/spec/dummy/config/events.rb +7 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/inflections.rb +10 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/routes.rb +58 -0
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/migrate/20130902222552_create_users.rb +10 -0
- data/spec/dummy/db/schema.rb +23 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/development.log +17 -0
- data/spec/dummy/log/production.log +0 -0
- data/spec/dummy/log/server.log +0 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +26 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/public/javascripts/application.js +2 -0
- data/spec/dummy/public/javascripts/controls.js +965 -0
- data/spec/dummy/public/javascripts/dragdrop.js +974 -0
- data/spec/dummy/public/javascripts/effects.js +1123 -0
- data/spec/dummy/public/javascripts/prototype.js +6001 -0
- data/spec/dummy/public/javascripts/rails.js +202 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/integration/connection_manager_spec.rb +135 -0
- data/spec/javascripts/support/jasmine.yml +52 -0
- data/spec/javascripts/support/jasmine_helper.rb +38 -0
- data/spec/javascripts/support/vendor/sinon-1.7.1.js +4343 -0
- data/spec/javascripts/websocket_rails/channel_spec.coffee +112 -0
- data/spec/javascripts/websocket_rails/event_spec.coffee +69 -0
- data/spec/javascripts/websocket_rails/helpers.coffee +6 -0
- data/spec/javascripts/websocket_rails/websocket_connection_spec.coffee +158 -0
- data/spec/javascripts/websocket_rails/websocket_rails_spec.coffee +274 -0
- data/spec/spec_helper.rb +41 -0
- data/spec/spec_helpers/matchers/route_matchers_spec.rb +109 -0
- data/spec/spec_helpers/matchers/trigger_matchers_spec.rb +247 -0
- data/spec/spec_helpers/spec_helper_event_spec.rb +66 -0
- data/spec/support/helper_methods.rb +42 -0
- data/spec/support/mock_web_socket.rb +41 -0
- data/spec/unit/base_controller_spec.rb +74 -0
- data/spec/unit/channel_manager_spec.rb +58 -0
- data/spec/unit/channel_spec.rb +169 -0
- data/spec/unit/connection_adapters/http_spec.rb +88 -0
- data/spec/unit/connection_adapters/web_socket_spec.rb +30 -0
- data/spec/unit/connection_adapters_spec.rb +259 -0
- data/spec/unit/connection_manager_spec.rb +148 -0
- data/spec/unit/controller_factory_spec.rb +76 -0
- data/spec/unit/data_store_spec.rb +106 -0
- data/spec/unit/dispatcher_spec.rb +203 -0
- data/spec/unit/event_map_spec.rb +120 -0
- data/spec/unit/event_queue_spec.rb +36 -0
- data/spec/unit/event_spec.rb +181 -0
- data/spec/unit/logging_spec.rb +162 -0
- data/spec/unit/synchronization_spec.rb +150 -0
- data/spec/unit/target_validator_spec.rb +88 -0
- data/spec/unit/user_manager_spec.rb +165 -0
- metadata +320 -0
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module WebsocketRails
|
|
4
|
+
module DataStore
|
|
5
|
+
describe Base do
|
|
6
|
+
it "extends Hash" do
|
|
7
|
+
subject.should be_a Hash
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
it "allows indifferent access" do
|
|
11
|
+
subject['key'] = true
|
|
12
|
+
subject[:key].should == true
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
describe "#instances" do
|
|
16
|
+
before do
|
|
17
|
+
Base.clear_all_instances
|
|
18
|
+
@connection = double('connection')
|
|
19
|
+
@controller = double('controller')
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it "keeps track of all instantiated instances" do
|
|
23
|
+
store_one = Base.new
|
|
24
|
+
store_two = Base.new
|
|
25
|
+
|
|
26
|
+
store_one.instances.count.should == 2
|
|
27
|
+
store_two.instances.count.should == 2
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it "separates instances based on class name" do
|
|
31
|
+
2.times { Connection.new(@connection) }
|
|
32
|
+
4.times { Controller.new(@controller) }
|
|
33
|
+
|
|
34
|
+
Connection.new(@connection).instances.count.should == 3
|
|
35
|
+
Controller.new(@controller).instances.count.should == 5
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
describe "#destroy!" do
|
|
40
|
+
before do
|
|
41
|
+
Base.clear_all_instances
|
|
42
|
+
@store = Base.new
|
|
43
|
+
@other = Base.new
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it "removes itself from the instances collection" do
|
|
47
|
+
@other.instances.count.should == 2
|
|
48
|
+
@store.destroy!
|
|
49
|
+
@other.instances.count.should == 1
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
describe "#collect_all" do
|
|
54
|
+
before do
|
|
55
|
+
Base.clear_all_instances
|
|
56
|
+
@store_one = Base.new
|
|
57
|
+
@store_two = Base.new
|
|
58
|
+
|
|
59
|
+
@store_one[:secret] = 'token_one'
|
|
60
|
+
@store_two[:secret] = 'token_two'
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
context "called without a block" do
|
|
64
|
+
it "returns an array of values for the specified key from all store instances" do
|
|
65
|
+
secrets = @store_one.collect_all(:secret)
|
|
66
|
+
secrets.should == ['token_one', 'token_two']
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
context "called with a block" do
|
|
71
|
+
it "yields each value to the block" do
|
|
72
|
+
@store_one.collect_all(:secret) do |item|
|
|
73
|
+
item.should be_in ['token_one', 'token_two']
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
describe Connection do
|
|
81
|
+
before do
|
|
82
|
+
@connection = double('connection')
|
|
83
|
+
@connection.stub(:client_id).and_return(1)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
let(:subject) { DataStore::Connection.new(@connection) }
|
|
87
|
+
|
|
88
|
+
it "stores a reference to it's connection" do
|
|
89
|
+
subject.connection.should == @connection
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
describe Controller do
|
|
94
|
+
before do
|
|
95
|
+
@controller = double('controller')
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
let(:subject) { DataStore::Controller.new(@controller) }
|
|
99
|
+
|
|
100
|
+
it "stores a reference to it's controller" do
|
|
101
|
+
subject.controller.should == @controller
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
end
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'support/mock_web_socket'
|
|
3
|
+
|
|
4
|
+
def rename_module_const(mod, old_name, new_name)
|
|
5
|
+
if mod.const_defined? old_name
|
|
6
|
+
mod.const_set(new_name, mod.const_get(old_name))
|
|
7
|
+
mod.send(:remove_const, old_name)
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def swizzle_module_const(mod, name, temp_name, &block)
|
|
12
|
+
rename_module_const(mod, name, temp_name)
|
|
13
|
+
yield block
|
|
14
|
+
rename_module_const(mod, temp_name, name)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def set_temp_module_const(mod, name, value, &block)
|
|
18
|
+
mod.const_set(name, value)
|
|
19
|
+
yield block
|
|
20
|
+
mod.send(:remove_const, name)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
module WebsocketRails
|
|
24
|
+
|
|
25
|
+
class EventTarget
|
|
26
|
+
attr_reader :_event, :_dispatcher, :test_method, :catch_all_method
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
describe Dispatcher do
|
|
30
|
+
|
|
31
|
+
let(:event) { double('Event').as_null_object }
|
|
32
|
+
let(:connection) { MockWebSocket.new }
|
|
33
|
+
let(:connection_manager) { double('connection_manager').as_null_object }
|
|
34
|
+
subject { Dispatcher.new(connection_manager) }
|
|
35
|
+
|
|
36
|
+
describe "#receive_encoded" do
|
|
37
|
+
context "receiving a new message" do
|
|
38
|
+
before do
|
|
39
|
+
Event.stub(:new_from_json).and_return( event )
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it "should be decoded from JSON and dispatched" do
|
|
43
|
+
subject.stub(:dispatch) do |dispatch_event|
|
|
44
|
+
dispatch_event.should == event
|
|
45
|
+
end
|
|
46
|
+
subject.receive_encoded(encoded_message,connection)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
describe "#receive" do
|
|
52
|
+
before { Event.stub(:new).and_return( event ) }
|
|
53
|
+
|
|
54
|
+
it "should dispatch a new event" do
|
|
55
|
+
subject.stub(:dispatch) do |dispatch_event|
|
|
56
|
+
dispatch_event.should == event
|
|
57
|
+
end
|
|
58
|
+
subject.receive(:test_event,{},connection)
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
context "dispatching an event" do
|
|
63
|
+
before do
|
|
64
|
+
EventMap.any_instance.stub(:routes_for).with(any_args).and_yield(EventTarget, :test_method)
|
|
65
|
+
event.stub(:name).and_return(:test_method)
|
|
66
|
+
event.stub(:data).and_return(:some_message)
|
|
67
|
+
event.stub(:connection).and_return(connection)
|
|
68
|
+
event.stub(:is_channel?).and_return(false)
|
|
69
|
+
event.stub(:is_invalid?).and_return(false)
|
|
70
|
+
event.stub(:is_internal?).and_return(false)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
it "should execute the correct method on the target class" do
|
|
74
|
+
EventTarget.any_instance.should_receive(:process_action).with(:test_method, event)
|
|
75
|
+
subject.dispatch(event)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
context "channel events" do
|
|
79
|
+
before do
|
|
80
|
+
subject.stub(:filtered_channels).and_return({})
|
|
81
|
+
end
|
|
82
|
+
it "should forward the data to the correct channel" do
|
|
83
|
+
event = Event.new 'test', :data => 'data', :channel => :awesome_channel
|
|
84
|
+
channel = double('channel')
|
|
85
|
+
channel.should_receive(:trigger_event).with(event)
|
|
86
|
+
WebsocketRails.should_receive(:[]).with(:awesome_channel).and_return(channel)
|
|
87
|
+
subject.dispatch event
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
context "filtered channel events" do
|
|
92
|
+
before do
|
|
93
|
+
subject.stub(:filtered_channels).and_return({:awesome_channel => EventTarget})
|
|
94
|
+
end
|
|
95
|
+
it "should execute the correct method on the target class" do
|
|
96
|
+
event = Event.new 'test_method', :data => 'some data', :channel => :awesome_channel
|
|
97
|
+
EventTarget.any_instance.should_receive(:process_action).with(:test_method, event)
|
|
98
|
+
subject.dispatch(event)
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
context "filtered channel catch all events" do
|
|
103
|
+
before do
|
|
104
|
+
subject.stub(:filtered_channels).and_return({:awesome_channel => [EventTarget, :catch_all_method]})
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
it "should execute the correct method on the target class" do
|
|
108
|
+
event = Event.new 'test_method', :data => 'some data', :channel => :awesome_channel
|
|
109
|
+
EventTarget.any_instance.should_receive(:process_action).with(:test_method, event)
|
|
110
|
+
EventTarget.any_instance.should_receive(:process_action).with(:catch_all_method, event)
|
|
111
|
+
subject.dispatch(event)
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
context "invalid events" do
|
|
116
|
+
before do
|
|
117
|
+
event.stub(:is_invalid?).and_return(true)
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
it "should not dispatch the event" do
|
|
121
|
+
subject.should_not_receive(:route)
|
|
122
|
+
subject.dispatch(event)
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
describe "#send_message" do
|
|
128
|
+
before do
|
|
129
|
+
@event = Event.new_from_json( encoded_message, connection )
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
it "should send a message to the event's connection object" do
|
|
133
|
+
connection.should_receive(:trigger).with(@event)
|
|
134
|
+
subject.send_message @event
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
describe "#broadcast_message" do
|
|
139
|
+
before do
|
|
140
|
+
connection_manager.stub(:connections).and_return({"connection_id" => connection})
|
|
141
|
+
@event = Event.new_from_json( encoded_message, connection )
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
it "should send a message to all connected clients" do
|
|
145
|
+
connection.should_receive(:trigger).with(@event)
|
|
146
|
+
subject.broadcast_message @event
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
describe 'record_invalid_defined?' do
|
|
151
|
+
|
|
152
|
+
it 'should return false when RecordInvalid is not defined' do
|
|
153
|
+
if Object.const_defined?('ActiveRecord')
|
|
154
|
+
swizzle_module_const(ActiveRecord, 'RecordInvalid','TempRecordInvalid') do
|
|
155
|
+
subject.send(:record_invalid_defined?).should be_false
|
|
156
|
+
end
|
|
157
|
+
else
|
|
158
|
+
set_temp_module_const(Object, 'ActiveRecord', Module.new) do
|
|
159
|
+
subject.send(:record_invalid_defined?).should be_false
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
it 'should return false when ActiveRecord is not defined' do
|
|
165
|
+
swizzle_module_const(Object, 'ActiveRecord', 'TempActiveRecord') do
|
|
166
|
+
subject.send(:record_invalid_defined?).should be_false
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
it 'should return true if ActiveRecord::RecordInvalid is defined' do
|
|
171
|
+
if Object.const_defined?('ActiveRecord')
|
|
172
|
+
if ActiveRecord.const_defined?('RecordInvalid')
|
|
173
|
+
subject.send(:record_invalid_defined?).should be_true
|
|
174
|
+
else
|
|
175
|
+
set_temp_module_const(ActiveRecord, 'RecordInvalid', Class.new) do
|
|
176
|
+
subject.send(:record_invalid_defined?).should be_true
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
else
|
|
180
|
+
set_temp_module_const(Object, 'ActiveRecord', Module.new) do
|
|
181
|
+
set_temp_module_const(ActiveRecord, 'RecordInvalid', Class.new) do
|
|
182
|
+
subject.send(:record_invalid_defined?).should be_true
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
context 'when ActiveRecord::RecordInvalid is not defined' do
|
|
190
|
+
|
|
191
|
+
it 'should check that exception can be converted to JSON' do
|
|
192
|
+
subject.should_receive(:record_invalid_defined?).and_return false
|
|
193
|
+
ex = double(:exception)
|
|
194
|
+
ex.should_receive(:respond_to?).with(:to_json).and_return true
|
|
195
|
+
exception_data = subject.send(:extract_exception_data, ex)
|
|
196
|
+
exception_data.should == ex
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
end
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
# this classes are outside the WebsocketRails namespace to better reflect the actual
|
|
4
|
+
# situation in a normal usage
|
|
5
|
+
|
|
6
|
+
class ProductController < WebsocketRails::BaseController
|
|
7
|
+
def update_product
|
|
8
|
+
true
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# name is chosen so that we know camelize is working correctly
|
|
13
|
+
class ComplexProductController < WebsocketRails::BaseController
|
|
14
|
+
|
|
15
|
+
def simplify_product
|
|
16
|
+
true
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
module WebsocketRails
|
|
23
|
+
describe EventMap do
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def define_test_events
|
|
27
|
+
WebsocketRails.config.route_block = nil
|
|
28
|
+
WebsocketRails::EventMap.describe do
|
|
29
|
+
subscribe :client_connected, :to => ChatController, :with_method => :new_user
|
|
30
|
+
|
|
31
|
+
namespace :product do
|
|
32
|
+
subscribe :update, :to => ProductController, :with_method => :update_product
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
namespace :complex_product do
|
|
36
|
+
subscribe :simplify, 'complex_product#simplify'
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
let(:dispatcher) { double('dispatcher').as_null_object }
|
|
43
|
+
subject { EventMap.new(dispatcher) }
|
|
44
|
+
before { define_test_events }
|
|
45
|
+
|
|
46
|
+
context "EventMap.describe" do
|
|
47
|
+
it "should store the event route block in the global configuration" do
|
|
48
|
+
WebsocketRails.config.route_block.should be_present
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
context "Events in the global namespace" do
|
|
53
|
+
|
|
54
|
+
it "should store the event in the correct namespace" do
|
|
55
|
+
subject.namespace.actions[:client_connected].should be_present
|
|
56
|
+
subject.namespace.name.should == :global
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it "should store the class constant and method name in the events hash" do
|
|
60
|
+
subject.namespace.actions[:client_connected].should == [[ChatController,:new_user]]
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
context "Events in a child namespace" do
|
|
66
|
+
|
|
67
|
+
before { @namespace = subject.namespace }
|
|
68
|
+
|
|
69
|
+
it "should store the event in the correct namespaces" do
|
|
70
|
+
@namespace.namespaces[:product].actions[:update].should be_present
|
|
71
|
+
@namespace.namespaces[:complex_product].actions[:simplify].should be_present
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
context "#routes_for" do
|
|
77
|
+
context "with events in the global namespace" do
|
|
78
|
+
it "should yield the controller class and action name for each route defined for an event" do
|
|
79
|
+
event = HelperMethods::MockEvent.new(:client_connected, [:global])
|
|
80
|
+
|
|
81
|
+
subject.routes_for(event) do |klass, method|
|
|
82
|
+
klass.should == ChatController
|
|
83
|
+
method.should == :new_user
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
context "with events in a child namespace" do
|
|
89
|
+
it "should yield the controller and action name for each route defined with a hash for an event" do
|
|
90
|
+
ProductController.any_instance.should_receive(:action_executed)
|
|
91
|
+
event = HelperMethods::MockEvent.new :update, [:global,:product]
|
|
92
|
+
|
|
93
|
+
subject.routes_for(event) do |klass, method|
|
|
94
|
+
controller = klass.new
|
|
95
|
+
controller.action_executed
|
|
96
|
+
controller.class.should == ProductController
|
|
97
|
+
method.should == :update_product
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
it "should yield the controller and action name for each route defined with a string for an event" do
|
|
103
|
+
ComplexProductController.any_instance.should_receive(:action_executed)
|
|
104
|
+
event = HelperMethods::MockEvent.new :simplify, [:global,:complex_product]
|
|
105
|
+
|
|
106
|
+
subject.routes_for(event) do |klass, method|
|
|
107
|
+
controller = klass.new
|
|
108
|
+
controller.action_executed
|
|
109
|
+
controller.class.should == ComplexProductController
|
|
110
|
+
method.should == :simplify
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
end
|
|
120
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module WebsocketRails
|
|
4
|
+
describe EventQueue do
|
|
5
|
+
|
|
6
|
+
describe "#initialize" do
|
|
7
|
+
it "should create an empty queue" do
|
|
8
|
+
subject.queue.should == []
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
describe "#<<" do
|
|
13
|
+
it "should add the item to the queue" do
|
|
14
|
+
subject << 'event'
|
|
15
|
+
subject.queue.should == ['event']
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
describe "#flush" do
|
|
20
|
+
before do
|
|
21
|
+
subject.queue << 'event'
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it "should yield all items in the queue" do
|
|
25
|
+
subject.flush do |event|
|
|
26
|
+
event.should == 'event'
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it "should empty the queue" do
|
|
31
|
+
subject.flush
|
|
32
|
+
subject.queue.should == []
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|