websocket-rails 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. data/CHANGELOG.md +11 -0
  2. data/Gemfile +7 -0
  3. data/README.md +15 -16
  4. data/lib/assets/javascripts/websocket_rails/channel.js +35 -0
  5. data/lib/assets/javascripts/websocket_rails/http_connection.js +68 -0
  6. data/lib/assets/javascripts/websocket_rails/main.js +4 -0
  7. data/lib/assets/javascripts/websocket_rails/websocket_connection.js +38 -0
  8. data/lib/assets/javascripts/websocket_rails/websocket_rails.js +100 -0
  9. data/lib/generators/websocket_rails/install/install_generator.rb +32 -0
  10. data/lib/generators/websocket_rails/install/templates/events.rb +14 -0
  11. data/lib/websocket-rails.rb +4 -0
  12. data/lib/websocket_rails/base_controller.rb +4 -2
  13. data/lib/websocket_rails/channel.rb +35 -0
  14. data/lib/websocket_rails/channel_manager.rb +28 -0
  15. data/lib/websocket_rails/connection_adapters.rb +35 -4
  16. data/lib/websocket_rails/connection_manager.rb +3 -1
  17. data/lib/websocket_rails/dispatcher.rb +22 -12
  18. data/lib/websocket_rails/event.rb +31 -17
  19. data/lib/websocket_rails/event_map.rb +14 -6
  20. data/lib/websocket_rails/event_queue.rb +27 -0
  21. data/lib/websocket_rails/internal_events.rb +19 -0
  22. data/lib/websocket_rails/version.rb +1 -1
  23. data/spec/dummy/config/initializers/events.rb +5 -5
  24. data/spec/dummy/log/test.log +180 -0
  25. data/spec/integration/connection_manager_spec.rb +21 -8
  26. data/spec/support/helper_methods.rb +2 -2
  27. data/spec/support/mock_web_socket.rb +4 -0
  28. data/spec/unit/channel_manager_spec.rb +29 -0
  29. data/spec/unit/channel_spec.rb +46 -0
  30. data/spec/unit/connection_adapters_spec.rb +20 -0
  31. data/spec/unit/dispatcher_spec.rb +13 -2
  32. data/spec/unit/event_map_spec.rb +2 -2
  33. data/spec/unit/event_queue_spec.rb +36 -0
  34. data/spec/unit/event_spec.rb +26 -3
  35. metadata +24 -28
  36. data/assets/javascripts/http_dispatcher.js +0 -78
  37. data/assets/javascripts/websocket_dispatcher.js +0 -66
@@ -11,15 +11,15 @@ module WebsocketRails
11
11
  def define_test_events
12
12
  WebsocketRails.route_block = nil
13
13
  WebsocketRails::EventMap.describe do
14
- subscribe :client_connected, to: ChatController, with_method: :new_user
15
- subscribe :change_username, to: ChatController, with_method: :change_username
16
- subscribe :client_error, to: ChatController, with_method: :error_occurred
17
- subscribe :client_disconnected, to: ChatController, with_method: :delete_user
14
+ subscribe :client_connected, :to => ChatController, :with_method => :new_user
15
+ subscribe :change_username, :to => ChatController, :with_method => :change_username
16
+ subscribe :client_error, :to => ChatController, :with_method => :error_occurred
17
+ subscribe :client_disconnected, :to => ChatController, :with_method => :delete_user
18
18
 
19
- subscribe :update_list, to: ChatController, with_method: :update_user_list
19
+ subscribe :update_list, :to => ChatController, :with_method => :update_user_list
20
20
 
21
21
  namespace :products do
22
- subscribe :update_list, to: ProductController, with_method: :update_list
22
+ subscribe :update_list, :to => ProductController, :with_method => :update_list
23
23
  end
24
24
  end
25
25
  end
@@ -41,7 +41,7 @@ module WebsocketRails
41
41
 
42
42
  context "active connections" do
43
43
  context "new message from client" do
44
- let(:test_message) { ['change_username',{user_name: 'Joe User'}] }
44
+ let(:test_message) { ['change_username',{:user_name => 'Joe User'}] }
45
45
  let(:encoded_message) { test_message.to_json }
46
46
 
47
47
  it "should execute the controller action associated with the received event" do
@@ -52,7 +52,7 @@ module WebsocketRails
52
52
  end
53
53
 
54
54
  context "new message from client under a namespace" do
55
- let(:test_message) { ['products.update_list',{product: 'x-ray-vision'}] }
55
+ let(:test_message) { ['products.update_list',{:product => 'x-ray-vision'}] }
56
56
  let(:encoded_message) { test_message.to_json }
57
57
 
58
58
  it "should execute the controller action under the correct namespace" do
@@ -62,6 +62,19 @@ module WebsocketRails
62
62
  socket.on_message( encoded_message )
63
63
  end
64
64
  end
65
+
66
+ context "subscribing to a channel" do
67
+ let(:channel_message) { ['websocket_rails.subscribe',{:channel => 'awesome_channel'}] }
68
+ let(:encoded_message) { channel_message.to_json }
69
+
70
+ it "should subscribe the connection to the correct channel" do
71
+ @server.call( env )
72
+ channel = WebsocketRails[:awesome_channel]
73
+ #channel.should_receive(:subscribe).once.with(socket)
74
+ Channel.any_instance.stub(:subscribe).and_raise(Exception)
75
+ socket.on_message encoded_message
76
+ end
77
+ end
65
78
 
66
79
  context "client error" do
67
80
  it "should execute the controller action associated with the 'client_error' event" do
@@ -11,11 +11,11 @@ module WebsocketRails
11
11
  end
12
12
 
13
13
  def encoded_message
14
- ['test_event',{user_name: 'Joe User'}].to_json
14
+ ['test_event',{:user_name => 'Joe User'}].to_json
15
15
  end
16
16
 
17
17
  def received_encoded_message(connection_id)
18
- [connection_id,'test_event',{user_name: 'Joe User'}].to_json
18
+ [connection_id,'test_event',{:user_name => 'Joe User'}].to_json
19
19
  end
20
20
 
21
21
  MockEvent = Struct.new(:name,:namespace)
@@ -25,6 +25,10 @@ module WebsocketRails
25
25
  true
26
26
  end
27
27
 
28
+ def trigger(event)
29
+ true
30
+ end
31
+
28
32
  def id
29
33
  object_id.to_i
30
34
  end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ module WebsocketRails
4
+
5
+ describe ".channel_manager" do
6
+ it "should load a new channel manager when first called" do
7
+ WebsocketRails.channel_manager.should be_a ChannelManager
8
+ end
9
+ end
10
+
11
+ describe ".[]" do
12
+ it "should delegate to channel manager" do
13
+ ChannelManager.any_instance.should_receive(:[]).with(:awesome_channel)
14
+ WebsocketRails[:awesome_channel]
15
+ end
16
+ end
17
+
18
+ describe ChannelManager do
19
+
20
+ describe "#[]" do
21
+ context "accessing a channel" do
22
+ it "should create the channel if it does not exist" do
23
+ subject[:awesome_channel].class.should == Channel
24
+ end
25
+ end
26
+ end
27
+
28
+ end
29
+ end
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+
3
+ module WebsocketRails
4
+ describe Channel do
5
+ subject { Channel.new :awesome_channel }
6
+
7
+ let(:connection) { double('connection') }
8
+
9
+ before do
10
+ connection.stub!(:trigger)
11
+ end
12
+
13
+ it "should maintain a pool of subscribed connections" do
14
+ subject.subscribers.should == []
15
+ end
16
+
17
+ describe "#subscribe" do
18
+ it "should add the connection to the subscriber pool" do
19
+ subject.subscribe connection
20
+ subject.subscribers.include?(connection).should be_true
21
+ end
22
+ end
23
+
24
+ describe "#trigger" do
25
+ it "should create a new event and trigger it on all subscribers" do
26
+ event = double('event').as_null_object
27
+ Event.should_receive(:new) do |name,data,options|
28
+ name.should == 'event'
29
+ data.should == 'data'
30
+ options.should be_a Hash
31
+ event
32
+ end
33
+ connection.should_receive(:trigger).with(event)
34
+ subject.subscribe connection
35
+ subject.trigger 'event', 'data'
36
+ end
37
+ end
38
+
39
+ describe "#trigger_event" do
40
+ it "should forward the event to the subscribers" do
41
+ subject.should_receive(:send_data).with('event')
42
+ subject.trigger_event 'event'
43
+ end
44
+ end
45
+ end
46
+ end
@@ -29,6 +29,7 @@ module WebsocketRails
29
29
  module ConnectionAdapters
30
30
  describe Base do
31
31
  let(:dispatcher) { double('Dispatcher').as_null_object }
32
+ let(:channel_manager) { double('ChannelManager').as_null_object }
32
33
  let(:event) { double('Event').as_null_object }
33
34
  before { Event.stub(:new_from_json).and_return(event) }
34
35
  subject { Base.new( env, dispatcher ) }
@@ -88,6 +89,25 @@ module WebsocketRails
88
89
  end
89
90
  end
90
91
 
92
+ describe "#enqueue" do
93
+ it "should add the event to the queue" do
94
+ subject.enqueue 'event'
95
+ subject.queue.queue.should == ['event']
96
+ end
97
+ end
98
+
99
+ describe "#trigger" do
100
+ it "should add the event to the queue" do
101
+ subject.stub(:flush)
102
+ subject.should_receive(:enqueue).with('event')
103
+ subject.trigger 'event'
104
+ end
105
+
106
+ it "should flush the queue" do
107
+ subject.should_receive(:flush)
108
+ subject.trigger 'event'
109
+ end
110
+ end
91
111
  end
92
112
  end
93
113
  end
@@ -50,6 +50,7 @@ module WebsocketRails
50
50
  event.stub(:name).and_return(:test_method)
51
51
  event.stub(:data).and_return(:some_message)
52
52
  event.stub(:connection).and_return(connection)
53
+ event.stub(:is_channel?).and_return(false)
53
54
  end
54
55
 
55
56
  it "should execute the correct method on the target class" do
@@ -61,6 +62,16 @@ module WebsocketRails
61
62
  subject.dispatch(event)
62
63
  @target._event.should == event
63
64
  end
65
+
66
+ context "channel events" do
67
+ it "should forward the data to the correct channel" do
68
+ event = Event.new 'test', 'data', :channel => :awesome_channel
69
+ channel = double('channel')
70
+ channel.should_receive(:trigger_event).with(event)
71
+ WebsocketRails.should_receive(:[]).with(:awesome_channel).and_return(channel)
72
+ subject.dispatch event
73
+ end
74
+ end
64
75
  end
65
76
 
66
77
  describe "#send_message" do
@@ -69,7 +80,7 @@ module WebsocketRails
69
80
  end
70
81
 
71
82
  it "should send a message to the event's connection object" do
72
- connection.should_receive(:send).with(@event.serialize)
83
+ connection.should_receive(:trigger).with(@event)
73
84
  subject.send_message @event
74
85
  end
75
86
  end
@@ -81,7 +92,7 @@ module WebsocketRails
81
92
  end
82
93
 
83
94
  it "should send a message to all connected clients" do
84
- connection.should_receive(:send).with(@event.serialize)
95
+ connection.should_receive(:trigger).with(@event)
85
96
  subject.broadcast_message @event
86
97
  end
87
98
  end
@@ -12,10 +12,10 @@ module WebsocketRails
12
12
  def define_test_events
13
13
  WebsocketRails.route_block = nil
14
14
  WebsocketRails::EventMap.describe do
15
- subscribe :client_connected, to: ChatController, with_method: :new_user
15
+ subscribe :client_connected, :to => ChatController, :with_method => :new_user
16
16
 
17
17
  namespace :product do
18
- subscribe :update, to: ProductController, with_method: :update_product
18
+ subscribe :update, :to => ProductController, :with_method => :update_product
19
19
  end
20
20
  end
21
21
  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
@@ -6,6 +6,7 @@ module WebsocketRails
6
6
  let(:encoded_message_string) { '["new_message","this is a message"]' }
7
7
  let(:namespace_encoded_message_string) { '["product.new_message","this is a message"]' }
8
8
  let(:namespace_encoded_message) { '["product.new_message",{"message":"this is a message"}]' }
9
+ let(:channel_encoded_message_string) { '["awesome_channel","new_message","this is a message"]' }
9
10
  let(:connection) { double('connection') }
10
11
 
11
12
  before { connection.stub!(:id).and_return(1) }
@@ -32,7 +33,7 @@ module WebsocketRails
32
33
  end
33
34
 
34
35
  describe ".new_on_open" do
35
- before { @event = Event.new_on_open connection, {message: 'connected'} }
36
+ before { @event = Event.new_on_open connection, {:message => 'connected'} }
36
37
 
37
38
  it "should create an event named :client_connected" do
38
39
  @event.name.should == :client_connected
@@ -67,18 +68,33 @@ module WebsocketRails
67
68
 
68
69
  context "new namespaced events" do
69
70
  it "should store the namespace in the namespace attribute" do
70
- event = Event.new "event", {}, connection, :namespace => :product
71
+ event = Event.new "event", {}, :connection => connection, :namespace => :product
71
72
  event.namespace.should == [:global,:product]
72
73
  event.name.should == :event
73
74
  end
74
75
 
75
76
  it "should store nested namespaces in the namespace attribute" do
76
- event = Event.new "event", {}, connection, :namespace => [:product,:x_ray_vision]
77
+ event = Event.new "event", {}, :connection => connection, :namespace => [:product,:x_ray_vision]
77
78
  event.namespace.should == [:global,:product,:x_ray_vision]
78
79
  event.name.should == :event
79
80
  end
80
81
  end
81
82
 
83
+ context "new channel events" do
84
+ it "should store the channel name in the channel attribute" do
85
+ event = Event.new "event", {}, :connection => connection, :channel => :awesome_channel
86
+ event.channel.should == :awesome_channel
87
+ event.name.should == :event
88
+ end
89
+ end
90
+
91
+ describe "#is_channel?" do
92
+ it "should return true if an event belongs to a channel" do
93
+ event = Event.new "event", "data", :channel => :awesome_channel
94
+ event.is_channel?.should be_true
95
+ end
96
+ end
97
+
82
98
  describe "#serialize" do
83
99
  context "messages in the global namespace" do
84
100
  it "should not add the global namespace to the event name" do
@@ -93,6 +109,13 @@ module WebsocketRails
93
109
  event.serialize.should == namespace_encoded_message_string
94
110
  end
95
111
  end
112
+
113
+ context "messages for a channel" do
114
+ it "should add the channel name as the first element of the serialized array" do
115
+ event = Event.new_from_json channel_encoded_message_string, connection
116
+ event.serialize.should == channel_encoded_message_string
117
+ end
118
+ end
96
119
  end
97
120
 
98
121
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: websocket-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -11,10 +11,10 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2012-06-22 00:00:00.000000000Z
14
+ date: 2012-06-30 00:00:00.000000000Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
- name: rack
17
+ name: rails
18
18
  requirement: !ruby/object:Gem::Requirement
19
19
  none: false
20
20
  requirements:
@@ -30,7 +30,7 @@ dependencies:
30
30
  - !ruby/object:Gem::Version
31
31
  version: '0'
32
32
  - !ruby/object:Gem::Dependency
33
- name: faye-websocket
33
+ name: rack
34
34
  requirement: !ruby/object:Gem::Requirement
35
35
  none: false
36
36
  requirements:
@@ -46,7 +46,7 @@ dependencies:
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
48
  - !ruby/object:Gem::Dependency
49
- name: thin
49
+ name: faye-websocket
50
50
  requirement: !ruby/object:Gem::Requirement
51
51
  none: false
52
52
  requirements:
@@ -62,30 +62,14 @@ dependencies:
62
62
  - !ruby/object:Gem::Version
63
63
  version: '0'
64
64
  - !ruby/object:Gem::Dependency
65
- name: rake
66
- requirement: !ruby/object:Gem::Requirement
67
- none: false
68
- requirements:
69
- - - ! '>='
70
- - !ruby/object:Gem::Version
71
- version: '0'
72
- type: :development
73
- prerelease: false
74
- version_requirements: !ruby/object:Gem::Requirement
75
- none: false
76
- requirements:
77
- - - ! '>='
78
- - !ruby/object:Gem::Version
79
- version: '0'
80
- - !ruby/object:Gem::Dependency
81
- name: rails
65
+ name: thin
82
66
  requirement: !ruby/object:Gem::Requirement
83
67
  none: false
84
68
  requirements:
85
69
  - - ! '>='
86
70
  - !ruby/object:Gem::Version
87
71
  version: '0'
88
- type: :development
72
+ type: :runtime
89
73
  prerelease: false
90
74
  version_requirements: !ruby/object:Gem::Requirement
91
75
  none: false
@@ -94,7 +78,7 @@ dependencies:
94
78
  - !ruby/object:Gem::Version
95
79
  version: '0'
96
80
  - !ruby/object:Gem::Dependency
97
- name: sqlite3
81
+ name: rake
98
82
  requirement: !ruby/object:Gem::Requirement
99
83
  none: false
100
84
  requirements:
@@ -133,8 +117,17 @@ executables:
133
117
  extensions: []
134
118
  extra_rdoc_files: []
135
119
  files:
120
+ - lib/assets/javascripts/websocket_rails/channel.js
121
+ - lib/assets/javascripts/websocket_rails/http_connection.js
122
+ - lib/assets/javascripts/websocket_rails/main.js
123
+ - lib/assets/javascripts/websocket_rails/websocket_connection.js
124
+ - lib/assets/javascripts/websocket_rails/websocket_rails.js
125
+ - lib/generators/websocket_rails/install/install_generator.rb
126
+ - lib/generators/websocket_rails/install/templates/events.rb
136
127
  - lib/websocket-rails.rb
137
128
  - lib/websocket_rails/base_controller.rb
129
+ - lib/websocket_rails/channel.rb
130
+ - lib/websocket_rails/channel_manager.rb
138
131
  - lib/websocket_rails/connection_adapters/http.rb
139
132
  - lib/websocket_rails/connection_adapters/web_socket.rb
140
133
  - lib/websocket_rails/connection_adapters.rb
@@ -144,11 +137,11 @@ files:
144
137
  - lib/websocket_rails/engine.rb
145
138
  - lib/websocket_rails/event.rb
146
139
  - lib/websocket_rails/event_map.rb
140
+ - lib/websocket_rails/event_queue.rb
141
+ - lib/websocket_rails/internal_events.rb
147
142
  - lib/websocket_rails/version.rb
148
143
  - config/routes.rb
149
144
  - bin/thin-socketrails
150
- - assets/javascripts/http_dispatcher.js
151
- - assets/javascripts/websocket_dispatcher.js
152
145
  - spec/dummy/app/controllers/application_controller.rb
153
146
  - spec/dummy/app/controllers/chat_controller.rb
154
147
  - spec/dummy/app/helpers/application_helper.rb
@@ -190,6 +183,8 @@ files:
190
183
  - spec/spec_helper.rb
191
184
  - spec/support/helper_methods.rb
192
185
  - spec/support/mock_web_socket.rb
186
+ - spec/unit/channel_manager_spec.rb
187
+ - spec/unit/channel_spec.rb
193
188
  - spec/unit/connection_adapters/http_spec.rb
194
189
  - spec/unit/connection_adapters/web_socket_spec.rb
195
190
  - spec/unit/connection_adapters_spec.rb
@@ -197,6 +192,7 @@ files:
197
192
  - spec/unit/data_store_spec.rb
198
193
  - spec/unit/dispatcher_spec.rb
199
194
  - spec/unit/event_map_spec.rb
195
+ - spec/unit/event_queue_spec.rb
200
196
  - spec/unit/event_spec.rb
201
197
  - MIT-LICENSE
202
198
  - Rakefile
@@ -217,7 +213,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
217
213
  version: '0'
218
214
  segments:
219
215
  - 0
220
- hash: 1310952573146011562
216
+ hash: -3091547921395116505
221
217
  required_rubygems_version: !ruby/object:Gem::Requirement
222
218
  none: false
223
219
  requirements:
@@ -226,7 +222,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
226
222
  version: '0'
227
223
  segments:
228
224
  - 0
229
- hash: 1310952573146011562
225
+ hash: -3091547921395116505
230
226
  requirements: []
231
227
  rubyforge_project: websocket-rails
232
228
  rubygems_version: 1.8.19