websocket-rails 0.1.5 → 0.1.6

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 (50) hide show
  1. data/CHANGELOG.md +22 -0
  2. data/Gemfile +4 -0
  3. data/README.md +66 -159
  4. data/Rakefile +31 -4
  5. data/bin/thin-socketrails +16 -1
  6. data/lib/assets/javascripts/websocket_rails/channel.js.coffee +23 -8
  7. data/lib/assets/javascripts/websocket_rails/event.js.coffee +40 -0
  8. data/lib/assets/javascripts/websocket_rails/http_connection.js.coffee +18 -10
  9. data/lib/assets/javascripts/websocket_rails/main.js +1 -0
  10. data/lib/assets/javascripts/websocket_rails/websocket_connection.js.coffee +15 -10
  11. data/lib/assets/javascripts/websocket_rails/websocket_rails.js.coffee +41 -23
  12. data/lib/websocket-rails.rb +4 -4
  13. data/lib/websocket_rails/base_controller.rb +61 -29
  14. data/lib/websocket_rails/channel.rb +14 -5
  15. data/lib/websocket_rails/channel_manager.rb +3 -1
  16. data/lib/websocket_rails/connection_adapters.rb +34 -12
  17. data/lib/websocket_rails/connection_manager.rb +4 -0
  18. data/lib/websocket_rails/dispatcher.rb +27 -3
  19. data/lib/websocket_rails/engine.rb +2 -5
  20. data/lib/websocket_rails/event.rb +87 -42
  21. data/lib/websocket_rails/event_map.rb +70 -20
  22. data/lib/websocket_rails/event_queue.rb +4 -0
  23. data/lib/websocket_rails/internal_events.rb +21 -3
  24. data/lib/websocket_rails/logging.rb +18 -0
  25. data/lib/websocket_rails/version.rb +1 -1
  26. data/spec/dummy/log/test.log +0 -429
  27. data/spec/integration/connection_manager_spec.rb +3 -5
  28. data/spec/javascripts/generated/assets/channel.js +98 -0
  29. data/spec/javascripts/generated/assets/event.js +78 -0
  30. data/spec/javascripts/generated/assets/http_connection.js +108 -0
  31. data/spec/javascripts/generated/assets/websocket_connection.js +66 -0
  32. data/spec/javascripts/generated/assets/websocket_rails.js +180 -0
  33. data/spec/javascripts/generated/specs/channel_spec.js +66 -0
  34. data/spec/javascripts/generated/specs/event_spec.js +107 -0
  35. data/spec/javascripts/generated/specs/websocket_connection_spec.js +117 -0
  36. data/spec/javascripts/generated/specs/websocket_rails_spec.js +232 -0
  37. data/spec/javascripts/support/jasmine.yml +44 -0
  38. data/spec/javascripts/support/jasmine_config.rb +63 -0
  39. data/spec/javascripts/support/vendor/sinon-1.3.4.js +3555 -0
  40. data/spec/javascripts/websocket_rails/channel_spec.coffee +51 -0
  41. data/spec/javascripts/websocket_rails/event_spec.coffee +69 -0
  42. data/spec/javascripts/websocket_rails/websocket_connection_spec.coffee +86 -0
  43. data/spec/javascripts/websocket_rails/websocket_rails_spec.coffee +166 -0
  44. data/spec/support/helper_methods.rb +10 -1
  45. data/spec/unit/channel_spec.rb +28 -4
  46. data/spec/unit/connection_adapters_spec.rb +17 -0
  47. data/spec/unit/connection_manager_spec.rb +1 -1
  48. data/spec/unit/dispatcher_spec.rb +1 -1
  49. data/spec/unit/event_spec.rb +15 -11
  50. metadata +22 -4
@@ -0,0 +1,108 @@
1
+
2
+ /*
3
+ HTTP Interface for the WebSocketRails client.
4
+ */
5
+
6
+
7
+ (function() {
8
+ var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
9
+
10
+ WebSocketRails.HttpConnection = (function() {
11
+
12
+ HttpConnection.prototype.httpFactories = function() {
13
+ return [
14
+ function() {
15
+ return new XMLHttpRequest();
16
+ }, function() {
17
+ return new ActiveXObject("Msxml2.XMLHTTP");
18
+ }, function() {
19
+ return new ActiveXObject("Msxml3.XMLHTTP");
20
+ }, function() {
21
+ return new ActiveXObject("Microsoft.XMLHTTP");
22
+ }
23
+ ];
24
+ };
25
+
26
+ HttpConnection.prototype.createXMLHttpObject = function() {
27
+ var factories, factory, xmlhttp, _i, _len;
28
+ xmlhttp = false;
29
+ factories = this.httpFactories();
30
+ for (_i = 0, _len = factories.length; _i < _len; _i++) {
31
+ factory = factories[_i];
32
+ try {
33
+ xmlhttp = factory();
34
+ } catch (e) {
35
+ continue;
36
+ }
37
+ break;
38
+ }
39
+ return xmlhttp;
40
+ };
41
+
42
+ function HttpConnection(url, dispatcher) {
43
+ this.url = url;
44
+ this.dispatcher = dispatcher;
45
+ this.flush_queue = __bind(this.flush_queue, this);
46
+
47
+ this.trigger = __bind(this.trigger, this);
48
+
49
+ this.parse_stream = __bind(this.parse_stream, this);
50
+
51
+ this.createXMLHttpObject = __bind(this.createXMLHttpObject, this);
52
+
53
+ this._conn = this.createXMLHttpObject();
54
+ this.last_pos = 0;
55
+ this.message_queue = [];
56
+ this._conn.onreadystatechange = this.parse_stream;
57
+ this._conn.open("GET", "/websocket", true);
58
+ this._conn.send();
59
+ }
60
+
61
+ HttpConnection.prototype.parse_stream = function() {
62
+ var data, decoded_data;
63
+ if (this._conn.readyState === 3) {
64
+ data = this._conn.responseText.substring(this.last_pos);
65
+ this.last_pos = this._conn.responseText.length;
66
+ data = data.replace("]][[", "],[");
67
+ decoded_data = JSON.parse(data);
68
+ return this.dispatcher.new_message(decoded_data);
69
+ }
70
+ };
71
+
72
+ HttpConnection.prototype.trigger = function(event) {
73
+ if (this.dispatcher.state !== 'connected') {
74
+ return this.message_queue.push(event);
75
+ } else {
76
+ return this.post_data(this.dispatcher.connection_id, event.serialize());
77
+ }
78
+ };
79
+
80
+ HttpConnection.prototype.post_data = function(connection_id, payload) {
81
+ return $.ajax("/websocket", {
82
+ type: 'POST',
83
+ data: {
84
+ client_id: connection_id,
85
+ data: payload
86
+ },
87
+ success: function() {}
88
+ });
89
+ };
90
+
91
+ HttpConnection.prototype.flush_queue = function(connection_id) {
92
+ var event, _i, _len, _ref;
93
+ _ref = this.message_queue;
94
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
95
+ event = _ref[_i];
96
+ if (connection_id != null) {
97
+ event.connection_id = this.dispatcher.connection_id;
98
+ }
99
+ this.trigger(event);
100
+ }
101
+ return this.message_queue = [];
102
+ };
103
+
104
+ return HttpConnection;
105
+
106
+ })();
107
+
108
+ }).call(this);
@@ -0,0 +1,66 @@
1
+
2
+ /*
3
+ WebSocket Interface for the WebSocketRails client.
4
+ */
5
+
6
+
7
+ (function() {
8
+ var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
9
+
10
+ WebSocketRails.WebSocketConnection = (function() {
11
+
12
+ function WebSocketConnection(url, dispatcher) {
13
+ this.url = url;
14
+ this.dispatcher = dispatcher;
15
+ this.flush_queue = __bind(this.flush_queue, this);
16
+
17
+ this.on_close = __bind(this.on_close, this);
18
+
19
+ this.on_message = __bind(this.on_message, this);
20
+
21
+ this.trigger = __bind(this.trigger, this);
22
+
23
+ if (!this.url.match(/^wss?:\/\//)) {
24
+ this.url = "ws://" + this.url;
25
+ }
26
+ this.message_queue = [];
27
+ this._conn = new WebSocket(this.url);
28
+ this._conn.onmessage = this.on_message;
29
+ this._conn.onclose = this.on_close;
30
+ }
31
+
32
+ WebSocketConnection.prototype.trigger = function(event) {
33
+ if (this.dispatcher.state !== 'connected') {
34
+ return this.message_queue.push(event);
35
+ } else {
36
+ return this._conn.send(event.serialize());
37
+ }
38
+ };
39
+
40
+ WebSocketConnection.prototype.on_message = function(event) {
41
+ var data;
42
+ data = JSON.parse(event.data);
43
+ return this.dispatcher.new_message(data);
44
+ };
45
+
46
+ WebSocketConnection.prototype.on_close = function(event) {
47
+ var close_event;
48
+ close_event = new WebSocketRails.Event(['connection_closed', {}]);
49
+ return this.dispatcher.dispatch(close_event);
50
+ };
51
+
52
+ WebSocketConnection.prototype.flush_queue = function() {
53
+ var event, _i, _len, _ref;
54
+ _ref = this.message_queue;
55
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
56
+ event = _ref[_i];
57
+ this._conn.send(event.serialize());
58
+ }
59
+ return this.message_queue = [];
60
+ };
61
+
62
+ return WebSocketConnection;
63
+
64
+ })();
65
+
66
+ }).call(this);
@@ -0,0 +1,180 @@
1
+
2
+ /*
3
+ WebsocketRails JavaScript Client
4
+
5
+ Setting up the dispatcher:
6
+ var dispatcher = new WebSocketRails('localhost:3000');
7
+ dispatcher.on_open = function() {
8
+ // trigger a server event immediately after opening connection
9
+ dispatcher.trigger('new_user',{user_name: 'guest'});
10
+ })
11
+
12
+ Triggering a new event on the server
13
+ dispatcherer.trigger('event_name',object_to_be_serialized_to_json);
14
+
15
+ Listening for new events from the server
16
+ dispatcher.bind('event_name', function(data) {
17
+ console.log(data.user_name);
18
+ });
19
+ */
20
+
21
+
22
+ (function() {
23
+ var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
24
+
25
+ window.WebSocketRails = (function() {
26
+
27
+ function WebSocketRails(url, use_websockets) {
28
+ this.url = url;
29
+ this.use_websockets = use_websockets != null ? use_websockets : true;
30
+ this.pong = __bind(this.pong, this);
31
+
32
+ this.supports_websockets = __bind(this.supports_websockets, this);
33
+
34
+ this.dispatch_channel = __bind(this.dispatch_channel, this);
35
+
36
+ this.subscribe_private = __bind(this.subscribe_private, this);
37
+
38
+ this.subscribe = __bind(this.subscribe, this);
39
+
40
+ this.dispatch = __bind(this.dispatch, this);
41
+
42
+ this.trigger_event = __bind(this.trigger_event, this);
43
+
44
+ this.trigger = __bind(this.trigger, this);
45
+
46
+ this.bind = __bind(this.bind, this);
47
+
48
+ this.connection_established = __bind(this.connection_established, this);
49
+
50
+ this.new_message = __bind(this.new_message, this);
51
+
52
+ this.state = 'connecting';
53
+ this.callbacks = {};
54
+ this.channels = {};
55
+ this.queue = {};
56
+ if (!(this.supports_websockets() && this.use_websockets)) {
57
+ this._conn = new WebSocketRails.HttpConnection(url, this);
58
+ } else {
59
+ this._conn = new WebSocketRails.WebSocketConnection(url, this);
60
+ }
61
+ this._conn.new_message = this.new_message;
62
+ }
63
+
64
+ WebSocketRails.prototype.new_message = function(data) {
65
+ var event, socket_message, _i, _len, _ref, _results;
66
+ _results = [];
67
+ for (_i = 0, _len = data.length; _i < _len; _i++) {
68
+ socket_message = data[_i];
69
+ event = new WebSocketRails.Event(socket_message);
70
+ if (event.is_result()) {
71
+ if ((_ref = this.queue[event.id]) != null) {
72
+ _ref.run_callbacks(event.success, event.data);
73
+ }
74
+ this.queue[event.id] = null;
75
+ } else if (event.is_channel()) {
76
+ this.dispatch_channel(event);
77
+ } else if (event.is_ping()) {
78
+ this.pong();
79
+ } else {
80
+ this.dispatch(event);
81
+ }
82
+ if (this.state === 'connecting' && event.name === 'client_connected') {
83
+ _results.push(this.connection_established(event.data));
84
+ } else {
85
+ _results.push(void 0);
86
+ }
87
+ }
88
+ return _results;
89
+ };
90
+
91
+ WebSocketRails.prototype.connection_established = function(data) {
92
+ this.state = 'connected';
93
+ this.connection_id = data.connection_id;
94
+ this._conn.flush_queue(data.connection_id);
95
+ if (this.on_open != null) {
96
+ return this.on_open(data);
97
+ }
98
+ };
99
+
100
+ WebSocketRails.prototype.bind = function(event_name, callback) {
101
+ var _base, _ref;
102
+ if ((_ref = (_base = this.callbacks)[event_name]) == null) {
103
+ _base[event_name] = [];
104
+ }
105
+ return this.callbacks[event_name].push(callback);
106
+ };
107
+
108
+ WebSocketRails.prototype.trigger = function(event_name, data, success_callback, failure_callback) {
109
+ var event;
110
+ event = new WebSocketRails.Event([event_name, data, this.connection_id], success_callback, failure_callback);
111
+ this.queue[event.id] = event;
112
+ return this._conn.trigger(event);
113
+ };
114
+
115
+ WebSocketRails.prototype.trigger_event = function(event) {
116
+ var _base, _name, _ref;
117
+ if ((_ref = (_base = this.queue)[_name = event.id]) == null) {
118
+ _base[_name] = event;
119
+ }
120
+ return this._conn.trigger(event);
121
+ };
122
+
123
+ WebSocketRails.prototype.dispatch = function(event) {
124
+ var callback, _i, _len, _ref, _results;
125
+ if (this.callbacks[event.name] == null) {
126
+ return;
127
+ }
128
+ _ref = this.callbacks[event.name];
129
+ _results = [];
130
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
131
+ callback = _ref[_i];
132
+ _results.push(callback(event.data));
133
+ }
134
+ return _results;
135
+ };
136
+
137
+ WebSocketRails.prototype.subscribe = function(channel_name) {
138
+ var channel;
139
+ if (this.channels[channel_name] == null) {
140
+ channel = new WebSocketRails.Channel(channel_name, this);
141
+ this.channels[channel_name] = channel;
142
+ return channel;
143
+ } else {
144
+ return this.channels[channel_name];
145
+ }
146
+ };
147
+
148
+ WebSocketRails.prototype.subscribe_private = function(channel_name) {
149
+ var channel;
150
+ if (this.channels[channel_name] == null) {
151
+ channel = new WebSocketRails.Channel(channel_name, this, true);
152
+ this.channels[channel_name] = channel;
153
+ return channel;
154
+ } else {
155
+ return this.channels[channel_name];
156
+ }
157
+ };
158
+
159
+ WebSocketRails.prototype.dispatch_channel = function(event) {
160
+ if (this.channels[event.channel] == null) {
161
+ return;
162
+ }
163
+ return this.channels[event.channel].dispatch(event.name, event.data);
164
+ };
165
+
166
+ WebSocketRails.prototype.supports_websockets = function() {
167
+ return typeof WebSocket === "function" || typeof WebSocket === "object";
168
+ };
169
+
170
+ WebSocketRails.prototype.pong = function() {
171
+ var pong;
172
+ pong = new WebSocketRails.Event(['websocket_rails.pong', {}, this.connection_id]);
173
+ return this._conn.trigger(pong);
174
+ };
175
+
176
+ return WebSocketRails;
177
+
178
+ })();
179
+
180
+ }).call(this);
@@ -0,0 +1,66 @@
1
+ (function() {
2
+
3
+ describe('WebSocketRails.Channel:', function() {
4
+ beforeEach(function() {
5
+ this.dispatcher = {
6
+ new_message: function() {
7
+ return true;
8
+ },
9
+ dispatch: function() {
10
+ return true;
11
+ },
12
+ trigger_event: function(event) {
13
+ return true;
14
+ },
15
+ state: 'connected',
16
+ connection_id: 12345
17
+ };
18
+ this.channel = new WebSocketRails.Channel('public', this.dispatcher);
19
+ return sinon.spy(this.dispatcher, 'trigger_event');
20
+ });
21
+ afterEach(function() {
22
+ return this.dispatcher.trigger_event.restore();
23
+ });
24
+ describe('public channels', function() {
25
+ beforeEach(function() {
26
+ this.channel = new WebSocketRails.Channel('forchan', this.dispatcher, false);
27
+ return this.event = this.dispatcher.trigger_event.lastCall.args[0];
28
+ });
29
+ it('should trigger an event containing the channel name', function() {
30
+ return expect(this.event.data.channel).toEqual('forchan');
31
+ });
32
+ it('should trigger an event containing the correct connection_id', function() {
33
+ return expect(this.event.connection_id).toEqual(12345);
34
+ });
35
+ it('should initialize an empty callbacks property', function() {
36
+ expect(this.channel._callbacks).toBeDefined();
37
+ return expect(this.channel._callbacks).toEqual({});
38
+ });
39
+ it('should be public', function() {
40
+ return expect(this.channel.is_private).toBeFalsy;
41
+ });
42
+ return describe('.bind', function() {
43
+ return it('should add a function to the callbacks collection', function() {
44
+ var test_func;
45
+ test_func = function() {};
46
+ this.channel.bind('event_name', test_func);
47
+ expect(this.channel._callbacks['event_name'].length).toBe(1);
48
+ return expect(this.channel._callbacks['event_name']).toContain(test_func);
49
+ });
50
+ });
51
+ });
52
+ return describe('private channels', function() {
53
+ beforeEach(function() {
54
+ this.channel = new WebSocketRails.Channel('forchan', this.dispatcher, true);
55
+ return this.event = this.dispatcher.trigger_event.lastCall.args[0];
56
+ });
57
+ it('should trigger a subscribe_private event when created', function() {
58
+ return expect(this.event.name).toEqual('websocket_rails.subscribe_private');
59
+ });
60
+ return it('should be private', function() {
61
+ return expect(this.channel.is_private).toBe(true);
62
+ });
63
+ });
64
+ });
65
+
66
+ }).call(this);
@@ -0,0 +1,107 @@
1
+ (function() {
2
+
3
+ describe('WebSocketRails.Event', function() {
4
+ describe('standard events', function() {
5
+ beforeEach(function() {
6
+ this.data = [
7
+ 'event', {
8
+ data: {
9
+ message: 'test'
10
+ }
11
+ }, 12345
12
+ ];
13
+ return this.event = new WebSocketRails.Event(this.data);
14
+ });
15
+ it('should generate an ID', function() {
16
+ return expect(this.event.id).not.toBeNull;
17
+ });
18
+ it('should have a connection ID', function() {
19
+ return expect(this.event.connection_id).toEqual(12345);
20
+ });
21
+ it('should assign the correct properties when passed a data array', function() {
22
+ expect(this.event.name).toEqual('event');
23
+ return expect(this.event.data.message).toEqual('test');
24
+ });
25
+ describe('.serialize()', function() {
26
+ return it('should serialize the event as JSON', function() {
27
+ var serialized;
28
+ this.event.id = 1;
29
+ serialized = "[\"event\",{\"id\":1,\"data\":{\"message\":\"test\"}}]";
30
+ return expect(this.event.serialize()).toEqual(serialized);
31
+ });
32
+ });
33
+ return describe('.is_channel()', function() {
34
+ return it('should be false', function() {
35
+ return expect(this.event.is_channel()).toEqual(false);
36
+ });
37
+ });
38
+ });
39
+ describe('channel events', function() {
40
+ beforeEach(function() {
41
+ this.data = [
42
+ 'event', {
43
+ channel: 'channel',
44
+ data: {
45
+ message: 'test'
46
+ }
47
+ }
48
+ ];
49
+ return this.event = new WebSocketRails.Event(this.data);
50
+ });
51
+ it('should assign the channel property', function() {
52
+ expect(this.event.channel).toEqual('channel');
53
+ expect(this.event.name).toEqual('event');
54
+ return expect(this.event.data.message).toEqual('test');
55
+ });
56
+ describe('.is_channel()', function() {
57
+ return it('should be true', function() {
58
+ return expect(this.event.is_channel()).toEqual(true);
59
+ });
60
+ });
61
+ return describe('.serialize()', function() {
62
+ return it('should serialize the event as JSON', function() {
63
+ var serialized;
64
+ this.event.id = 1;
65
+ serialized = "[\"event\",{\"id\":1,\"channel\":\"channel\",\"data\":{\"message\":\"test\"}}]";
66
+ return expect(this.event.serialize()).toEqual(serialized);
67
+ });
68
+ });
69
+ });
70
+ return describe('.run_callbacks()', function() {
71
+ beforeEach(function() {
72
+ var failure_func, success_func;
73
+ success_func = function(data) {
74
+ return data;
75
+ };
76
+ failure_func = function(data) {
77
+ return data;
78
+ };
79
+ this.data = [
80
+ 'event', {
81
+ data: {
82
+ message: 'test'
83
+ }
84
+ }, 12345
85
+ ];
86
+ return this.event = new WebSocketRails.Event(this.data, success_func, failure_func);
87
+ });
88
+ describe('when successful', function() {
89
+ it('should run the success callback when passed true', function() {
90
+ return expect(this.event.run_callbacks(true, 'success')).toEqual('success');
91
+ });
92
+ return it('should not run the failure callback', function() {
93
+ return expect(this.event.run_callbacks(true, 'success')).toBeUndefined;
94
+ });
95
+ });
96
+ return describe('when failure', function() {
97
+ it('should run the failure callback when passed true', function() {
98
+ return expect(this.event.run_callbacks(false, 'failure')).toEqual('failure');
99
+ });
100
+ return it('should not run the failure callback', function() {
101
+ return expect(this.event.run_callbacks(false, 'failure')).toBeUndefined;
102
+ });
103
+ });
104
+ });
105
+ });
106
+
107
+ }).call(this);
@@ -0,0 +1,117 @@
1
+ (function() {
2
+
3
+ describe('WebsocketRails.WebSocketConnection:', function() {
4
+ beforeEach(function() {
5
+ var dispatcher;
6
+ dispatcher = {
7
+ new_message: function() {
8
+ return true;
9
+ },
10
+ dispatch: function() {
11
+ return true;
12
+ },
13
+ state: 'connected'
14
+ };
15
+ window.WebSocket = function(url) {
16
+ this.url = url;
17
+ return this.send = function() {
18
+ return true;
19
+ };
20
+ };
21
+ return this.connection = new WebSocketRails.WebSocketConnection('localhost:3000/websocket', dispatcher);
22
+ });
23
+ describe('constructor', function() {
24
+ it('should set the onmessage event on the WebSocket object to this.on_message', function() {
25
+ return expect(this.connection._conn.onmessage).toEqual(this.connection.on_message);
26
+ });
27
+ it('should set the onclose event on the WebSocket object to this.on_close', function() {
28
+ return expect(this.connection._conn.onclose).toEqual(this.connection.on_close);
29
+ });
30
+ describe('with ssl', function() {
31
+ return it('should not add the ws:// prefix to the URL', function() {
32
+ var connection;
33
+ connection = new WebSocketRails.WebSocketConnection('wss://localhost.com');
34
+ return expect(connection.url).toEqual('wss://localhost.com');
35
+ });
36
+ });
37
+ return describe('without ssl', function() {
38
+ return it('should add the ws:// prefix to the URL', function() {
39
+ return expect(this.connection.url).toEqual('ws://localhost:3000/websocket');
40
+ });
41
+ });
42
+ });
43
+ describe('.trigger', function() {
44
+ describe('before the connection has been fully established', function() {
45
+ return it('should queue up the events', function() {
46
+ var event, mock_queue;
47
+ this.connection.dispatcher.state = 'connecting';
48
+ event = new WebSocketRails.Event(['event', 'message']);
49
+ mock_queue = sinon.mock(this.connection.message_queue);
50
+ return mock_queue.expects('push').once().withArgs(event);
51
+ });
52
+ });
53
+ return describe('after the connection has been fully established', function() {
54
+ return it('should encode the data and send it through the WebSocket object', function() {
55
+ var event, mock_connection;
56
+ this.connection.dispatcher.state = 'connected';
57
+ event = new WebSocketRails.Event(['event', 'message']);
58
+ this.connection._conn = {
59
+ send: function() {
60
+ return true;
61
+ }
62
+ };
63
+ mock_connection = sinon.mock(this.connection._conn);
64
+ mock_connection.expects('send').once().withArgs(event.serialize());
65
+ this.connection.trigger(event);
66
+ return mock_connection.verify();
67
+ });
68
+ });
69
+ });
70
+ describe('.on_message', function() {
71
+ return it('should decode the message and pass it to the dispatcher', function() {
72
+ var encoded_data, event, mock_dispatcher;
73
+ encoded_data = JSON.stringify(['event', 'message']);
74
+ event = {
75
+ data: encoded_data
76
+ };
77
+ mock_dispatcher = sinon.mock(this.connection.dispatcher);
78
+ mock_dispatcher.expects('new_message').once().withArgs(JSON.parse(encoded_data));
79
+ this.connection.on_message(event);
80
+ return mock_dispatcher.verify();
81
+ });
82
+ });
83
+ describe('.on_close', function() {
84
+ return it('should dispatch the connection_closed event', function() {
85
+ var mock_dispatcher;
86
+ mock_dispatcher = sinon.mock(this.connection.dispatcher);
87
+ mock_dispatcher.expects('dispatch').once();
88
+ this.connection.on_close();
89
+ return mock_dispatcher.verify();
90
+ });
91
+ });
92
+ return describe('.flush_queue', function() {
93
+ beforeEach(function() {
94
+ this.event = new WebSocketRails.Event(['event', 'message']);
95
+ this.connection.message_queue.push(this.event);
96
+ return this.connection._conn = {
97
+ send: function() {
98
+ return true;
99
+ }
100
+ };
101
+ });
102
+ it('should send out all of the messages in the queue', function() {
103
+ var mock_connection;
104
+ mock_connection = sinon.mock(this.connection._conn);
105
+ mock_connection.expects('send').once().withArgs(this.event.serialize());
106
+ this.connection.flush_queue();
107
+ return mock_connection.verify();
108
+ });
109
+ return it('should empty the queue after sending', function() {
110
+ expect(this.connection.message_queue.length).toEqual(1);
111
+ this.connection.flush_queue();
112
+ return expect(this.connection.message_queue.length).toEqual(0);
113
+ });
114
+ });
115
+ });
116
+
117
+ }).call(this);