websocket-rails 0.1.3 → 0.1.4

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 (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