pusher-fake 0.1.4 → 0.1.5
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.
- data/features/step_definitions/event_steps.rb +1 -1
- data/features/support/application/public/javascripts/vendor/{pusher-1.11.js → pusher-1.12.5.js} +190 -153
- data/features/support/application/views/index.erb +1 -1
- data/lib/pusher-fake.rb +1 -1
- data/lib/pusher-fake/server/application.rb +6 -47
- data/spec/lib/pusher-fake/server/application_spec.rb +31 -112
- metadata +24 -24
data/features/support/application/public/javascripts/vendor/{pusher-1.11.js → pusher-1.12.5.js}
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* Pusher JavaScript Library v1.12.
|
|
2
|
+
* Pusher JavaScript Library v1.12.5
|
|
3
3
|
* http://pusherapp.com/
|
|
4
4
|
*
|
|
5
5
|
* Copyright 2011, Pusher
|
|
@@ -183,11 +183,17 @@
|
|
|
183
183
|
};
|
|
184
184
|
|
|
185
185
|
// Pusher defaults
|
|
186
|
-
Pusher.VERSION = '1.12.
|
|
187
|
-
|
|
186
|
+
Pusher.VERSION = '1.12.5';
|
|
187
|
+
// WS connection parameters
|
|
188
188
|
Pusher.host = 'ws.pusherapp.com';
|
|
189
189
|
Pusher.ws_port = 80;
|
|
190
190
|
Pusher.wss_port = 443;
|
|
191
|
+
// SockJS fallback parameters
|
|
192
|
+
Pusher.sockjs_host = 'sockjs.pusher.com';
|
|
193
|
+
Pusher.sockjs_http_port = 80
|
|
194
|
+
Pusher.sockjs_https_port = 443
|
|
195
|
+
Pusher.sockjs_path = "/pusher"
|
|
196
|
+
// Other settings
|
|
191
197
|
Pusher.channel_auth_endpoint = '/pusher/auth';
|
|
192
198
|
Pusher.cdn_http = 'http://js.pusher.com/'
|
|
193
199
|
Pusher.cdn_https = 'https://d3dy5gmtp8yhk7.cloudfront.net/'
|
|
@@ -220,44 +226,67 @@ Example:
|
|
|
220
226
|
emitter.bind('foo_event', function(data){ alert(data)} );
|
|
221
227
|
|
|
222
228
|
// Bind to all
|
|
223
|
-
emitter.bind_all(function(
|
|
229
|
+
emitter.bind_all(function(eventName, data){ alert(data) });
|
|
224
230
|
|
|
225
231
|
--------------------------------------------------------*/
|
|
232
|
+
|
|
233
|
+
function CallbackRegistry() {
|
|
234
|
+
this._callbacks = {};
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
CallbackRegistry.prototype.get = function(eventName) {
|
|
238
|
+
return this._callbacks[this._prefix(eventName)];
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
CallbackRegistry.prototype.add = function(eventName, callback) {
|
|
242
|
+
var prefixedEventName = this._prefix(eventName);
|
|
243
|
+
this._callbacks[prefixedEventName] = this._callbacks[prefixedEventName] || [];
|
|
244
|
+
this._callbacks[prefixedEventName].push(callback);
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
CallbackRegistry.prototype.remove = function(eventName, callback) {
|
|
248
|
+
if(this.get(eventName)) {
|
|
249
|
+
var index = Pusher.Util.arrayIndexOf(this.get(eventName), callback);
|
|
250
|
+
this._callbacks[this._prefix(eventName)].splice(index, 1);
|
|
251
|
+
}
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
CallbackRegistry.prototype._prefix = function(eventName) {
|
|
255
|
+
return "_" + eventName;
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
|
|
226
259
|
function EventsDispatcher(failThrough) {
|
|
227
|
-
this.callbacks =
|
|
260
|
+
this.callbacks = new CallbackRegistry();
|
|
228
261
|
this.global_callbacks = [];
|
|
229
262
|
// Run this function when dispatching an event when no callbacks defined
|
|
230
263
|
this.failThrough = failThrough;
|
|
231
264
|
}
|
|
232
265
|
|
|
233
|
-
EventsDispatcher.prototype.bind = function(
|
|
234
|
-
this.callbacks
|
|
235
|
-
this.callbacks[event_name].push(callback);
|
|
266
|
+
EventsDispatcher.prototype.bind = function(eventName, callback) {
|
|
267
|
+
this.callbacks.add(eventName, callback);
|
|
236
268
|
return this;// chainable
|
|
237
269
|
};
|
|
238
|
-
|
|
270
|
+
|
|
239
271
|
EventsDispatcher.prototype.unbind = function(eventName, callback) {
|
|
240
|
-
|
|
241
|
-
var index = Pusher.Util.arrayIndexOf(this.callbacks[eventName], callback);
|
|
242
|
-
this.callbacks[eventName].splice(index, 1);
|
|
243
|
-
}
|
|
272
|
+
this.callbacks.remove(eventName, callback);
|
|
244
273
|
return this;
|
|
245
274
|
};
|
|
246
275
|
|
|
247
|
-
EventsDispatcher.prototype.emit = function(
|
|
276
|
+
EventsDispatcher.prototype.emit = function(eventName, data) {
|
|
248
277
|
// Global callbacks
|
|
249
278
|
for (var i = 0; i < this.global_callbacks.length; i++) {
|
|
250
|
-
this.global_callbacks[i](
|
|
279
|
+
this.global_callbacks[i](eventName, data);
|
|
251
280
|
}
|
|
252
281
|
|
|
253
282
|
// Event callbacks
|
|
254
|
-
var callbacks = this.callbacks
|
|
283
|
+
var callbacks = this.callbacks.get(eventName);
|
|
255
284
|
if (callbacks) {
|
|
256
285
|
for (var i = 0; i < callbacks.length; i++) {
|
|
257
286
|
callbacks[i](data);
|
|
258
287
|
}
|
|
259
288
|
} else if (this.failThrough) {
|
|
260
|
-
this.failThrough(
|
|
289
|
+
this.failThrough(eventName, data)
|
|
261
290
|
}
|
|
262
291
|
|
|
263
292
|
return this;
|
|
@@ -402,32 +431,30 @@ Example:
|
|
|
402
431
|
'connected': ['permanentlyClosing', 'waiting'],
|
|
403
432
|
'impermanentlyClosing': ['waiting', 'permanentlyClosing'],
|
|
404
433
|
'permanentlyClosing': ['permanentlyClosed'],
|
|
405
|
-
'permanentlyClosed': ['waiting'],
|
|
434
|
+
'permanentlyClosed': ['waiting', 'failed'],
|
|
406
435
|
'failed': ['permanentlyClosed']
|
|
407
436
|
};
|
|
408
437
|
|
|
409
438
|
|
|
410
|
-
|
|
411
|
-
var
|
|
412
|
-
var UNSUCCESSFUL_OPEN_ATTEMPT_ADDITIONAL_TIMEOUT = 2000;
|
|
413
|
-
var UNSUCCESSFUL_CONNECTED_ATTEMPT_ADDITIONAL_TIMEOUT = 2000;
|
|
439
|
+
var OPEN_TIMEOUT_INCREMENT = 2000;
|
|
440
|
+
var CONNECTED_TIMEOUT_INCREMENT = 2000;
|
|
414
441
|
|
|
415
|
-
var
|
|
416
|
-
var
|
|
417
|
-
var MAX_CONNECTED_ATTEMPT_TIMEOUT = 5 * UNSUCCESSFUL_CONNECTED_ATTEMPT_ADDITIONAL_TIMEOUT;
|
|
442
|
+
var MAX_OPEN_TIMEOUT = 10000;
|
|
443
|
+
var MAX_CONNECTED_TIMEOUT = 10000;
|
|
418
444
|
|
|
419
445
|
function resetConnectionParameters(connection) {
|
|
420
446
|
connection.connectionWait = 0;
|
|
421
447
|
|
|
422
|
-
if (Pusher.TransportType === '
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
448
|
+
if (Pusher.TransportType === 'native') {
|
|
449
|
+
connection.openTimeout = 4000;
|
|
450
|
+
} else if (Pusher.TransportType === 'flash') {
|
|
451
|
+
connection.openTimeout = 7000;
|
|
452
|
+
} else { // SockJS
|
|
453
|
+
connection.openTimeout = 6000;
|
|
427
454
|
}
|
|
428
455
|
connection.connectedTimeout = 2000;
|
|
429
456
|
connection.connectionSecure = connection.compulsorySecure;
|
|
430
|
-
connection.
|
|
457
|
+
connection.failedAttempts = 0;
|
|
431
458
|
}
|
|
432
459
|
|
|
433
460
|
function Connection(key, options) {
|
|
@@ -435,6 +462,7 @@ Example:
|
|
|
435
462
|
|
|
436
463
|
Pusher.EventsDispatcher.call(this);
|
|
437
464
|
|
|
465
|
+
this.ping = true
|
|
438
466
|
this.options = Pusher.Util.extend({encrypted: false}, options);
|
|
439
467
|
|
|
440
468
|
this.netInfo = new Pusher.NetInfo();
|
|
@@ -474,22 +502,25 @@ Example:
|
|
|
474
502
|
},
|
|
475
503
|
|
|
476
504
|
waitingPre: function() {
|
|
477
|
-
if (self.
|
|
478
|
-
self.
|
|
479
|
-
|
|
505
|
+
if (self.netInfo.isOnLine()) {
|
|
506
|
+
if (self.failedAttempts < 2) {
|
|
507
|
+
updateState('connecting');
|
|
508
|
+
} else {
|
|
509
|
+
updateState('unavailable');
|
|
510
|
+
// Delay 10s between connection attempts on entering unavailable
|
|
511
|
+
self.connectionWait = 10000;
|
|
512
|
+
}
|
|
480
513
|
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
updateState('unavailable');
|
|
485
|
-
}
|
|
514
|
+
if (self.connectionWait > 0) {
|
|
515
|
+
self.emit('connecting_in', connectionDelay());
|
|
516
|
+
}
|
|
486
517
|
|
|
487
|
-
// When in the unavailable state we attempt to connect, but don't
|
|
488
|
-
// broadcast that fact
|
|
489
|
-
if (self.netInfo.isOnLine()) {
|
|
490
518
|
self._waitingTimer = setTimeout(function() {
|
|
519
|
+
// Even when unavailable we try connecting (not changing state)
|
|
491
520
|
self._machine.transition('connecting');
|
|
492
521
|
}, connectionDelay());
|
|
522
|
+
} else {
|
|
523
|
+
updateState('unavailable');
|
|
493
524
|
}
|
|
494
525
|
},
|
|
495
526
|
|
|
@@ -507,12 +538,27 @@ Example:
|
|
|
507
538
|
return;
|
|
508
539
|
}
|
|
509
540
|
|
|
510
|
-
var
|
|
511
|
-
Pusher.
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
541
|
+
var path = connectPath(self.key);
|
|
542
|
+
if (Pusher.TransportType === 'sockjs') {
|
|
543
|
+
Pusher.debug('Connecting to sockjs', Pusher.sockjs);
|
|
544
|
+
var url = buildSockJSURL(self.connectionSecure);
|
|
545
|
+
|
|
546
|
+
self.ping = false
|
|
547
|
+
self.socket = new SockJS(url);
|
|
548
|
+
self.socket.onopen = function() {
|
|
549
|
+
// SockJS does not yet support custom paths and query params
|
|
550
|
+
self.socket.send(JSON.stringify({path: path}));
|
|
551
|
+
self._machine.transition('open');
|
|
552
|
+
}
|
|
553
|
+
} else {
|
|
554
|
+
var url = connectBaseURL(self.connectionSecure) + path;
|
|
555
|
+
Pusher.debug('Connecting', url);
|
|
556
|
+
self.socket = new Pusher.Transport(url);
|
|
557
|
+
self.socket.onopen = function() {
|
|
558
|
+
self._machine.transition('open');
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
|
|
516
562
|
self.socket.onclose = transitionToWaiting;
|
|
517
563
|
self.socket.onerror = ws_onError;
|
|
518
564
|
|
|
@@ -616,44 +662,45 @@ Example:
|
|
|
616
662
|
-----------------------------------------------*/
|
|
617
663
|
|
|
618
664
|
function updateConnectionParameters() {
|
|
619
|
-
if (self.
|
|
620
|
-
self.
|
|
621
|
-
}
|
|
622
|
-
|
|
623
|
-
if (self.openTimeout < MAX_OPEN_ATTEMPT_TIMEOUT) {
|
|
624
|
-
self.openTimeout += UNSUCCESSFUL_OPEN_ATTEMPT_ADDITIONAL_TIMEOUT;
|
|
665
|
+
if (self.openTimeout < MAX_OPEN_TIMEOUT) {
|
|
666
|
+
self.openTimeout += OPEN_TIMEOUT_INCREMENT;
|
|
625
667
|
}
|
|
626
668
|
|
|
627
|
-
if (self.connectedTimeout <
|
|
628
|
-
self.connectedTimeout +=
|
|
669
|
+
if (self.connectedTimeout < MAX_CONNECTED_TIMEOUT) {
|
|
670
|
+
self.connectedTimeout += CONNECTED_TIMEOUT_INCREMENT;
|
|
629
671
|
}
|
|
630
672
|
|
|
673
|
+
// Toggle between ws & wss
|
|
631
674
|
if (self.compulsorySecure !== true) {
|
|
632
675
|
self.connectionSecure = !self.connectionSecure;
|
|
633
676
|
}
|
|
634
677
|
|
|
635
|
-
self.
|
|
678
|
+
self.failedAttempts++;
|
|
636
679
|
}
|
|
637
680
|
|
|
638
|
-
function
|
|
639
|
-
|
|
640
|
-
var
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
// been loaded via HTTPS.
|
|
644
|
-
//
|
|
645
|
-
// FUTURE: Always connect using SSL.
|
|
646
|
-
//
|
|
647
|
-
if (isSecure || document.location.protocol === 'https:') {
|
|
648
|
-
port = Pusher.wss_port;
|
|
649
|
-
protocol = 'wss://';
|
|
650
|
-
}
|
|
681
|
+
function connectBaseURL(isSecure) {
|
|
682
|
+
// Always connect with SSL if the current page served over https
|
|
683
|
+
var ssl = (isSecure || document.location.protocol === 'https:');
|
|
684
|
+
var port = ssl ? Pusher.wss_port : Pusher.ws_port;
|
|
685
|
+
var scheme = ssl ? 'wss://' : 'ws://';
|
|
651
686
|
|
|
652
|
-
|
|
687
|
+
return scheme + Pusher.host + ':' + port;
|
|
688
|
+
}
|
|
653
689
|
|
|
654
|
-
|
|
690
|
+
function connectPath(key) {
|
|
691
|
+
var flash = (Pusher.TransportType === "flash") ? "true" : "false";
|
|
692
|
+
var path = '/app/' + key + '?protocol=5&client=js'
|
|
655
693
|
+ '&version=' + Pusher.VERSION
|
|
656
694
|
+ '&flash=' + flash;
|
|
695
|
+
return path;
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
function buildSockJSURL(isSecure) {
|
|
699
|
+
var ssl = (isSecure || document.location.protocol === 'https:');
|
|
700
|
+
var port = ssl ? Pusher.sockjs_https_port : Pusher.sockjs_http_port;
|
|
701
|
+
var scheme = ssl ? 'https://' : 'http://';
|
|
702
|
+
|
|
703
|
+
return scheme + Pusher.sockjs_host + ':' + port + Pusher.sockjs_path;
|
|
657
704
|
}
|
|
658
705
|
|
|
659
706
|
// callback for close and retry. Used on timeouts.
|
|
@@ -664,13 +711,15 @@ Example:
|
|
|
664
711
|
function resetActivityCheck() {
|
|
665
712
|
if (self._activityTimer) { clearTimeout(self._activityTimer); }
|
|
666
713
|
// Send ping after inactivity
|
|
667
|
-
self.
|
|
668
|
-
self.send_event('pusher:ping', {})
|
|
669
|
-
// Wait for pong response
|
|
714
|
+
if (self.ping) {
|
|
670
715
|
self._activityTimer = setTimeout(function() {
|
|
671
|
-
self.
|
|
672
|
-
|
|
673
|
-
|
|
716
|
+
self.send_event('pusher:ping', {})
|
|
717
|
+
// Wait for pong response
|
|
718
|
+
self._activityTimer = setTimeout(function() {
|
|
719
|
+
self.socket.close();
|
|
720
|
+
}, (self.options.pong_timeout || Pusher.pong_timeout))
|
|
721
|
+
}, (self.options.activity_timeout || Pusher.activity_timeout))
|
|
722
|
+
}
|
|
674
723
|
}
|
|
675
724
|
|
|
676
725
|
function stopActivityCheck() {
|
|
@@ -700,11 +749,6 @@ Example:
|
|
|
700
749
|
WebSocket Callbacks
|
|
701
750
|
-----------------------------------------------*/
|
|
702
751
|
|
|
703
|
-
// no-op, as we only care when we get pusher:connection_established
|
|
704
|
-
function ws_onopen() {
|
|
705
|
-
self._machine.transition('open');
|
|
706
|
-
};
|
|
707
|
-
|
|
708
752
|
function handleCloseCode(code, message) {
|
|
709
753
|
// first inform the end-developer of this error
|
|
710
754
|
self.emit('error', {type: 'PusherError', data: {code: code, message: message}});
|
|
@@ -819,7 +863,7 @@ Example:
|
|
|
819
863
|
|
|
820
864
|
Connection.prototype.connect = function() {
|
|
821
865
|
// no WebSockets
|
|
822
|
-
if (
|
|
866
|
+
if (!this._machine.is('failed') && !Pusher.Transport) {
|
|
823
867
|
this._machine.transition('failed');
|
|
824
868
|
}
|
|
825
869
|
// initial open of connection
|
|
@@ -840,17 +884,12 @@ Example:
|
|
|
840
884
|
|
|
841
885
|
Connection.prototype.send = function(data) {
|
|
842
886
|
if (this._machine.is('connected')) {
|
|
843
|
-
//
|
|
844
|
-
// 1. Open page/tab, connect WS, get some data.
|
|
845
|
-
// 2. Switch tab or close Mobile Safari and wait for WS connection to get closed (probably by server).
|
|
846
|
-
// 3. Switch back to tab or open Mobile Safari and Mobile Safari crashes.
|
|
847
|
-
// The problem is that WS tries to send data on closed WS connection before it realises it is closed.
|
|
848
|
-
// The timeout means that by the time the send happens, the WS readyState correctly reflects closed state.
|
|
887
|
+
// Workaround for MobileSafari bug (see https://gist.github.com/2052006)
|
|
849
888
|
var self = this;
|
|
850
889
|
setTimeout(function() {
|
|
851
890
|
self.socket.send(data);
|
|
852
891
|
}, 0);
|
|
853
|
-
return true;
|
|
892
|
+
return true;
|
|
854
893
|
} else {
|
|
855
894
|
return false;
|
|
856
895
|
}
|
|
@@ -1145,73 +1184,83 @@ Example:
|
|
|
1145
1184
|
}
|
|
1146
1185
|
};
|
|
1147
1186
|
}).call(this);
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
elem.addEventListener('load', callback, false)
|
|
1154
|
-
}
|
|
1155
|
-
} else {
|
|
1156
|
-
handleScriptLoaded = function(elem, callback) {
|
|
1187
|
+
// _require(dependencies, callback) takes an array of dependency urls and a
|
|
1188
|
+
// callback to call when all the dependecies have finished loading
|
|
1189
|
+
var _require = (function() {
|
|
1190
|
+
function handleScriptLoaded(elem, callback) {
|
|
1191
|
+
if (document.addEventListener) {
|
|
1192
|
+
elem.addEventListener('load', callback, false);
|
|
1193
|
+
} else {
|
|
1157
1194
|
elem.attachEvent('onreadystatechange', function () {
|
|
1158
|
-
if(elem.readyState == 'loaded' || elem.readyState == 'complete')
|
|
1159
|
-
|
|
1195
|
+
if (elem.readyState == 'loaded' || elem.readyState == 'complete') {
|
|
1196
|
+
callback();
|
|
1197
|
+
}
|
|
1198
|
+
});
|
|
1160
1199
|
}
|
|
1161
1200
|
}
|
|
1162
1201
|
|
|
1163
|
-
|
|
1164
|
-
var
|
|
1165
|
-
|
|
1202
|
+
function addScript(src, callback) {
|
|
1203
|
+
var head = document.getElementsByTagName('head')[0];
|
|
1204
|
+
var script = document.createElement('script');
|
|
1205
|
+
script.setAttribute('src', src);
|
|
1206
|
+
script.setAttribute("type","text/javascript");
|
|
1207
|
+
script.setAttribute('async', true);
|
|
1166
1208
|
|
|
1167
|
-
function
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
// Opera needs the timeout for page initialization weirdness
|
|
1171
|
-
setTimeout(callback, 0);
|
|
1172
|
-
}
|
|
1173
|
-
}
|
|
1209
|
+
handleScriptLoaded(script, function() {
|
|
1210
|
+
callback();
|
|
1211
|
+
});
|
|
1174
1212
|
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
var head = document.getElementsByTagName('head')[0];
|
|
1178
|
-
var script = document.createElement('script');
|
|
1179
|
-
script.setAttribute('src', src);
|
|
1180
|
-
script.setAttribute("type","text/javascript");
|
|
1181
|
-
script.setAttribute('async', true);
|
|
1213
|
+
head.appendChild(script);
|
|
1214
|
+
}
|
|
1182
1215
|
|
|
1183
|
-
|
|
1184
|
-
|
|
1216
|
+
return function(deps, callback) {
|
|
1217
|
+
var deps_loaded = 0;
|
|
1218
|
+
for (var i = 0; i < deps.length; i++) {
|
|
1219
|
+
addScript(deps[i], function() {
|
|
1220
|
+
if (deps.length == ++deps_loaded) {
|
|
1221
|
+
// This setTimeout is a workaround for an Opera issue
|
|
1222
|
+
setTimeout(callback, 0);
|
|
1223
|
+
}
|
|
1185
1224
|
});
|
|
1186
|
-
|
|
1187
|
-
head.appendChild(script);
|
|
1188
|
-
}
|
|
1189
|
-
|
|
1190
|
-
for(var i = 0; i < dep_length; i++) {
|
|
1191
|
-
addScript(deps[i], callback);
|
|
1192
1225
|
}
|
|
1193
1226
|
}
|
|
1194
1227
|
})();
|
|
1195
1228
|
|
|
1196
1229
|
;(function() {
|
|
1230
|
+
// Support Firefox versions which prefix WebSocket
|
|
1231
|
+
if (!window['WebSocket'] && window['MozWebSocket']) {
|
|
1232
|
+
window['WebSocket'] = window['MozWebSocket']
|
|
1233
|
+
}
|
|
1234
|
+
|
|
1235
|
+
if (window['WebSocket']) {
|
|
1236
|
+
Pusher.Transport = window['WebSocket'];
|
|
1237
|
+
Pusher.TransportType = 'native';
|
|
1238
|
+
}
|
|
1239
|
+
|
|
1197
1240
|
var cdn = (document.location.protocol == 'http:') ? Pusher.cdn_http : Pusher.cdn_https;
|
|
1198
1241
|
var root = cdn + Pusher.VERSION;
|
|
1199
1242
|
var deps = [];
|
|
1200
1243
|
|
|
1201
|
-
if (window['JSON']
|
|
1244
|
+
if (!window['JSON']) {
|
|
1202
1245
|
deps.push(root + '/json2' + Pusher.dependency_suffix + '.js');
|
|
1203
1246
|
}
|
|
1204
|
-
if (window['WebSocket']
|
|
1205
|
-
//
|
|
1247
|
+
if (!window['WebSocket']) {
|
|
1248
|
+
// Try to use web-socket-js (flash WebSocket emulation)
|
|
1206
1249
|
window.WEB_SOCKET_DISABLE_AUTO_INITIALIZATION = true;
|
|
1250
|
+
window.WEB_SOCKET_SUPPRESS_CROSS_DOMAIN_SWF_ERROR = true;
|
|
1207
1251
|
deps.push(root + '/flashfallback' + Pusher.dependency_suffix + '.js');
|
|
1208
1252
|
}
|
|
1209
1253
|
|
|
1210
1254
|
var initialize = function() {
|
|
1211
|
-
if (window['WebSocket']
|
|
1255
|
+
if (window['WebSocket']) {
|
|
1256
|
+
// Initialize function in the case that we have native WebSocket support
|
|
1257
|
+
return function() {
|
|
1258
|
+
Pusher.ready();
|
|
1259
|
+
}
|
|
1260
|
+
} else {
|
|
1261
|
+
// Initialize function for fallback case
|
|
1212
1262
|
return function() {
|
|
1213
|
-
|
|
1214
|
-
if (window['WebSocket'] !== undefined && window['MozWebSocket'] === undefined) {
|
|
1263
|
+
if (window['WebSocket']) {
|
|
1215
1264
|
// window['WebSocket'] is a flash emulation of WebSocket
|
|
1216
1265
|
Pusher.Transport = window['WebSocket'];
|
|
1217
1266
|
Pusher.TransportType = 'flash';
|
|
@@ -1222,31 +1271,19 @@ var _require = (function () {
|
|
|
1222
1271
|
})
|
|
1223
1272
|
WebSocket.__initialize();
|
|
1224
1273
|
} else {
|
|
1225
|
-
//
|
|
1226
|
-
Pusher.
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
return function() {
|
|
1233
|
-
// This is because Mozilla have decided to
|
|
1234
|
-
// prefix the WebSocket constructor with "Moz".
|
|
1235
|
-
if (window['MozWebSocket'] !== undefined) {
|
|
1236
|
-
Pusher.Transport = window['MozWebSocket'];
|
|
1237
|
-
} else {
|
|
1238
|
-
Pusher.Transport = window['WebSocket'];
|
|
1274
|
+
// web-socket-js cannot initialize (most likely flash not installed)
|
|
1275
|
+
sockjsPath = root + '/sockjs' + Pusher.dependency_suffix + '.js';
|
|
1276
|
+
_require([sockjsPath], function() {
|
|
1277
|
+
Pusher.Transport = SockJS;
|
|
1278
|
+
Pusher.TransportType = 'sockjs';
|
|
1279
|
+
Pusher.ready();
|
|
1280
|
+
})
|
|
1239
1281
|
}
|
|
1240
|
-
// We have some form of a native websocket,
|
|
1241
|
-
// even if the constructor is prefixed:
|
|
1242
|
-
Pusher.TransportType = 'native';
|
|
1243
|
-
|
|
1244
|
-
// Initialise Pusher.
|
|
1245
|
-
Pusher.ready();
|
|
1246
1282
|
}
|
|
1247
1283
|
}
|
|
1248
1284
|
}();
|
|
1249
1285
|
|
|
1286
|
+
// Allows calling a function when the document body is available
|
|
1250
1287
|
var ondocumentbody = function(callback) {
|
|
1251
1288
|
var load_body = function() {
|
|
1252
1289
|
document.body ? callback() : setTimeout(load_body, 0);
|
data/lib/pusher-fake.rb
CHANGED
|
@@ -2,61 +2,20 @@ module PusherFake
|
|
|
2
2
|
module Server
|
|
3
3
|
class Application
|
|
4
4
|
# Process an API request by emitting the event with data to the
|
|
5
|
-
# requested
|
|
5
|
+
# requested channels.
|
|
6
6
|
#
|
|
7
7
|
# @param [Hash] environment The request environment.
|
|
8
8
|
# @return [Rack::Response] A successful response.
|
|
9
9
|
def self.call(environment)
|
|
10
|
-
|
|
10
|
+
request = Rack::Request.new(environment)
|
|
11
|
+
event = Yajl::Parser.parse(request.body.read)
|
|
11
12
|
|
|
12
|
-
|
|
13
|
+
event["channels"].each do |channel|
|
|
14
|
+
Channel.factory(channel).emit(event["name"], event["data"])
|
|
15
|
+
end
|
|
13
16
|
|
|
14
17
|
Rack::Response.new("{}").finish
|
|
15
18
|
end
|
|
16
|
-
|
|
17
|
-
# Determine the channel name from the request path.
|
|
18
|
-
#
|
|
19
|
-
# @return [String] The channel name.
|
|
20
|
-
def self.channel
|
|
21
|
-
matcher = %r{/apps/#{PusherFake.configuration.app_id}/channels/(.+)/events}i
|
|
22
|
-
matches = path.match(matcher)
|
|
23
|
-
matches[1]
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
# Parse and return the event data from the request JSON.
|
|
27
|
-
#
|
|
28
|
-
# @return [Hash] The parsed event data.
|
|
29
|
-
def self.data
|
|
30
|
-
Yajl::Parser.parse(request.body.read)
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
# Get the environment.
|
|
34
|
-
#
|
|
35
|
-
# @return [Hash] The request environment.
|
|
36
|
-
def self.environment
|
|
37
|
-
@environment
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
# Get the event name from the request parameters.
|
|
41
|
-
#
|
|
42
|
-
# @return [String] The event name.
|
|
43
|
-
def self.event
|
|
44
|
-
request.params["name"]
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
# Get the request path from the environment.
|
|
48
|
-
#
|
|
49
|
-
# @return [String] The request path.
|
|
50
|
-
def self.path
|
|
51
|
-
environment["PATH_INFO"]
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
# Create a +Rack::Request+ from the environment.
|
|
55
|
-
#
|
|
56
|
-
# @return [Rack::Request] The request object.
|
|
57
|
-
def self.request
|
|
58
|
-
Rack::Request.new(environment)
|
|
59
|
-
end
|
|
60
19
|
end
|
|
61
20
|
end
|
|
62
21
|
end
|
|
@@ -1,35 +1,52 @@
|
|
|
1
1
|
require "spec_helper"
|
|
2
2
|
|
|
3
3
|
describe PusherFake::Server::Application, ".call" do
|
|
4
|
-
let(:
|
|
5
|
-
let(:
|
|
6
|
-
let(:
|
|
7
|
-
let(:
|
|
8
|
-
let(:
|
|
9
|
-
let(:
|
|
4
|
+
let(:body) { stub(read: json) }
|
|
5
|
+
let(:data) { mock }
|
|
6
|
+
let(:json) { mock }
|
|
7
|
+
let(:name) { "event-name" }
|
|
8
|
+
let(:event) { { "channels" => channels, "name" => name, "data" => data } }
|
|
9
|
+
let(:request) { stub(body: body) }
|
|
10
|
+
let(:channels) { ["channel-1", "channel-2"] }
|
|
11
|
+
let(:response) { mock }
|
|
12
|
+
let(:channel_1) { stub(emit: true) }
|
|
13
|
+
let(:channel_2) { stub(emit: true) }
|
|
14
|
+
let(:environment) { mock }
|
|
10
15
|
|
|
11
16
|
subject { PusherFake::Server::Application }
|
|
12
17
|
|
|
13
18
|
before do
|
|
14
|
-
subject.stubs(channel: channel_name, data: data, event: event)
|
|
15
|
-
PusherFake::Channel.stubs(factory: channel)
|
|
16
19
|
response.stubs(finish: response)
|
|
20
|
+
|
|
21
|
+
Yajl::Parser.stubs(parse: event)
|
|
22
|
+
Rack::Request.stubs(new: request)
|
|
17
23
|
Rack::Response.stubs(new: response)
|
|
24
|
+
PusherFake::Channel.stubs(:factory).with(channels[0]).returns(channel_1)
|
|
25
|
+
PusherFake::Channel.stubs(:factory).with(channels[1]).returns(channel_2)
|
|
18
26
|
end
|
|
19
27
|
|
|
20
|
-
it "
|
|
28
|
+
it "creates a request" do
|
|
21
29
|
subject.call(environment)
|
|
22
|
-
|
|
30
|
+
Rack::Request.should have_received(:new).with(environment)
|
|
23
31
|
end
|
|
24
32
|
|
|
25
|
-
it "
|
|
33
|
+
it "parses the request body as JSON" do
|
|
26
34
|
subject.call(environment)
|
|
27
|
-
|
|
35
|
+
Yajl::Parser.should have_received(:parse).with(json)
|
|
28
36
|
end
|
|
29
37
|
|
|
30
|
-
it "
|
|
38
|
+
it "creates channels by name" do
|
|
31
39
|
subject.call(environment)
|
|
32
|
-
|
|
40
|
+
|
|
41
|
+
channels.each do |channel|
|
|
42
|
+
PusherFake::Channel.should have_received(:factory).with(channel)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it "emits the event to the channels" do
|
|
47
|
+
subject.call(environment)
|
|
48
|
+
channel_1.should have_received(:emit).with(name, data)
|
|
49
|
+
channel_2.should have_received(:emit).with(name, data)
|
|
33
50
|
end
|
|
34
51
|
|
|
35
52
|
it "creates a Rack response with an empty JSON object" do
|
|
@@ -46,101 +63,3 @@ describe PusherFake::Server::Application, ".call" do
|
|
|
46
63
|
subject.call(environment).should == response
|
|
47
64
|
end
|
|
48
65
|
end
|
|
49
|
-
|
|
50
|
-
describe PusherFake::Server::Application, ".channel" do
|
|
51
|
-
let(:path) { "/apps/PUSHER_APP_ID/channels/#{channel}/events" }
|
|
52
|
-
let(:channel) { "channel-name" }
|
|
53
|
-
|
|
54
|
-
subject { PusherFake::Server::Application }
|
|
55
|
-
|
|
56
|
-
before do
|
|
57
|
-
subject.stubs(path: path)
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
it "returns the channel name from the path" do
|
|
61
|
-
subject.channel.should == channel
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
context "with a custom application ID" do
|
|
65
|
-
let(:path) { "/apps/#{app_id}/channels/#{channel}/events" }
|
|
66
|
-
let(:app_id) { "test-id" }
|
|
67
|
-
|
|
68
|
-
before do
|
|
69
|
-
PusherFake.configuration.app_id = app_id
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
it "returns the channel name from the path" do
|
|
73
|
-
subject.channel.should == channel
|
|
74
|
-
end
|
|
75
|
-
end
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
describe PusherFake::Server::Application, ".data" do
|
|
79
|
-
let(:data) { mock }
|
|
80
|
-
let(:body) { stub(read: json) }
|
|
81
|
-
let(:json) { mock }
|
|
82
|
-
let(:request) { stub(body: body) }
|
|
83
|
-
|
|
84
|
-
subject { PusherFake::Server::Application }
|
|
85
|
-
|
|
86
|
-
before do
|
|
87
|
-
subject.stubs(request: request)
|
|
88
|
-
Yajl::Parser.stubs(parse: data)
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
it "parses the request body as JSON" do
|
|
92
|
-
subject.data
|
|
93
|
-
Yajl::Parser.should have_received(:parse).with(json)
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
it "returns the parsed JSON" do
|
|
97
|
-
subject.data.should == data
|
|
98
|
-
end
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
describe PusherFake::Server::Application, ".event" do
|
|
102
|
-
let(:name) { mock }
|
|
103
|
-
let(:params) { { "name" => name } }
|
|
104
|
-
let(:request) { stub(params: params) }
|
|
105
|
-
|
|
106
|
-
subject { PusherFake::Server::Application }
|
|
107
|
-
|
|
108
|
-
before do
|
|
109
|
-
subject.stubs(request: request)
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
it "creates a reqeust from the environment" do
|
|
113
|
-
subject.event.should == name
|
|
114
|
-
end
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
describe PusherFake::Server::Application, ".path" do
|
|
118
|
-
let(:path) { mock }
|
|
119
|
-
let(:environment) { { "PATH_INFO" => path } }
|
|
120
|
-
|
|
121
|
-
subject { PusherFake::Server::Application }
|
|
122
|
-
|
|
123
|
-
before do
|
|
124
|
-
subject.stubs(environment: environment)
|
|
125
|
-
end
|
|
126
|
-
|
|
127
|
-
it "returns the path for the environment" do
|
|
128
|
-
subject.path.should == path
|
|
129
|
-
end
|
|
130
|
-
end
|
|
131
|
-
|
|
132
|
-
describe PusherFake::Server::Application, ".request" do
|
|
133
|
-
let(:environment) { mock }
|
|
134
|
-
|
|
135
|
-
subject { PusherFake::Server::Application }
|
|
136
|
-
|
|
137
|
-
before do
|
|
138
|
-
Rack::Request.stubs(:new)
|
|
139
|
-
subject.stubs(environment: environment)
|
|
140
|
-
end
|
|
141
|
-
|
|
142
|
-
it "creates a reqeust from the environment" do
|
|
143
|
-
subject.request
|
|
144
|
-
Rack::Request.should have_received(:new).with(environment)
|
|
145
|
-
end
|
|
146
|
-
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: pusher-fake
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.5
|
|
5
5
|
prerelease:
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2012-
|
|
12
|
+
date: 2012-11-13 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: em-websocket
|
|
@@ -50,7 +50,7 @@ dependencies:
|
|
|
50
50
|
requirements:
|
|
51
51
|
- - '='
|
|
52
52
|
- !ruby/object:Gem::Version
|
|
53
|
-
version: 1.
|
|
53
|
+
version: 1.5.0
|
|
54
54
|
type: :runtime
|
|
55
55
|
prerelease: false
|
|
56
56
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -58,7 +58,7 @@ dependencies:
|
|
|
58
58
|
requirements:
|
|
59
59
|
- - '='
|
|
60
60
|
- !ruby/object:Gem::Version
|
|
61
|
-
version: 1.
|
|
61
|
+
version: 1.5.0
|
|
62
62
|
- !ruby/object:Gem::Dependency
|
|
63
63
|
name: yajl-ruby
|
|
64
64
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -82,7 +82,7 @@ dependencies:
|
|
|
82
82
|
requirements:
|
|
83
83
|
- - '='
|
|
84
84
|
- !ruby/object:Gem::Version
|
|
85
|
-
version: 1.
|
|
85
|
+
version: 1.2.0
|
|
86
86
|
type: :development
|
|
87
87
|
prerelease: false
|
|
88
88
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -90,7 +90,7 @@ dependencies:
|
|
|
90
90
|
requirements:
|
|
91
91
|
- - '='
|
|
92
92
|
- !ruby/object:Gem::Version
|
|
93
|
-
version: 1.
|
|
93
|
+
version: 1.2.0
|
|
94
94
|
- !ruby/object:Gem::Dependency
|
|
95
95
|
name: bundler
|
|
96
96
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -114,7 +114,7 @@ dependencies:
|
|
|
114
114
|
requirements:
|
|
115
115
|
- - '='
|
|
116
116
|
- !ruby/object:Gem::Version
|
|
117
|
-
version: 1.1.
|
|
117
|
+
version: 1.1.3
|
|
118
118
|
type: :development
|
|
119
119
|
prerelease: false
|
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -122,7 +122,7 @@ dependencies:
|
|
|
122
122
|
requirements:
|
|
123
123
|
- - '='
|
|
124
124
|
- !ruby/object:Gem::Version
|
|
125
|
-
version: 1.1.
|
|
125
|
+
version: 1.1.3
|
|
126
126
|
- !ruby/object:Gem::Dependency
|
|
127
127
|
name: capybara-webkit
|
|
128
128
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -130,7 +130,7 @@ dependencies:
|
|
|
130
130
|
requirements:
|
|
131
131
|
- - '='
|
|
132
132
|
- !ruby/object:Gem::Version
|
|
133
|
-
version: 0.
|
|
133
|
+
version: 0.13.0
|
|
134
134
|
type: :development
|
|
135
135
|
prerelease: false
|
|
136
136
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -138,7 +138,7 @@ dependencies:
|
|
|
138
138
|
requirements:
|
|
139
139
|
- - '='
|
|
140
140
|
- !ruby/object:Gem::Version
|
|
141
|
-
version: 0.
|
|
141
|
+
version: 0.13.0
|
|
142
142
|
- !ruby/object:Gem::Dependency
|
|
143
143
|
name: cucumber
|
|
144
144
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -162,7 +162,7 @@ dependencies:
|
|
|
162
162
|
requirements:
|
|
163
163
|
- - '='
|
|
164
164
|
- !ruby/object:Gem::Version
|
|
165
|
-
version: 0.
|
|
165
|
+
version: 0.10.0
|
|
166
166
|
type: :development
|
|
167
167
|
prerelease: false
|
|
168
168
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -170,7 +170,7 @@ dependencies:
|
|
|
170
170
|
requirements:
|
|
171
171
|
- - '='
|
|
172
172
|
- !ruby/object:Gem::Version
|
|
173
|
-
version: 0.
|
|
173
|
+
version: 0.10.0
|
|
174
174
|
- !ruby/object:Gem::Dependency
|
|
175
175
|
name: rake
|
|
176
176
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -178,7 +178,7 @@ dependencies:
|
|
|
178
178
|
requirements:
|
|
179
179
|
- - '='
|
|
180
180
|
- !ruby/object:Gem::Version
|
|
181
|
-
version: 0.
|
|
181
|
+
version: 10.0.0
|
|
182
182
|
type: :development
|
|
183
183
|
prerelease: false
|
|
184
184
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -186,7 +186,7 @@ dependencies:
|
|
|
186
186
|
requirements:
|
|
187
187
|
- - '='
|
|
188
188
|
- !ruby/object:Gem::Version
|
|
189
|
-
version: 0.
|
|
189
|
+
version: 10.0.0
|
|
190
190
|
- !ruby/object:Gem::Dependency
|
|
191
191
|
name: redcarpet
|
|
192
192
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -194,7 +194,7 @@ dependencies:
|
|
|
194
194
|
requirements:
|
|
195
195
|
- - '='
|
|
196
196
|
- !ruby/object:Gem::Version
|
|
197
|
-
version: 2.
|
|
197
|
+
version: 2.2.2
|
|
198
198
|
type: :development
|
|
199
199
|
prerelease: false
|
|
200
200
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -202,7 +202,7 @@ dependencies:
|
|
|
202
202
|
requirements:
|
|
203
203
|
- - '='
|
|
204
204
|
- !ruby/object:Gem::Version
|
|
205
|
-
version: 2.
|
|
205
|
+
version: 2.2.2
|
|
206
206
|
- !ruby/object:Gem::Dependency
|
|
207
207
|
name: rspec
|
|
208
208
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -226,7 +226,7 @@ dependencies:
|
|
|
226
226
|
requirements:
|
|
227
227
|
- - '='
|
|
228
228
|
- !ruby/object:Gem::Version
|
|
229
|
-
version: 1.3.
|
|
229
|
+
version: 1.3.3
|
|
230
230
|
type: :development
|
|
231
231
|
prerelease: false
|
|
232
232
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -234,7 +234,7 @@ dependencies:
|
|
|
234
234
|
requirements:
|
|
235
235
|
- - '='
|
|
236
236
|
- !ruby/object:Gem::Version
|
|
237
|
-
version: 1.3.
|
|
237
|
+
version: 1.3.3
|
|
238
238
|
- !ruby/object:Gem::Dependency
|
|
239
239
|
name: yard
|
|
240
240
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -242,7 +242,7 @@ dependencies:
|
|
|
242
242
|
requirements:
|
|
243
243
|
- - '='
|
|
244
244
|
- !ruby/object:Gem::Version
|
|
245
|
-
version: 0.8.
|
|
245
|
+
version: 0.8.3
|
|
246
246
|
type: :development
|
|
247
247
|
prerelease: false
|
|
248
248
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -250,7 +250,7 @@ dependencies:
|
|
|
250
250
|
requirements:
|
|
251
251
|
- - '='
|
|
252
252
|
- !ruby/object:Gem::Version
|
|
253
|
-
version: 0.8.
|
|
253
|
+
version: 0.8.3
|
|
254
254
|
description: A fake Pusher server for development and testing.
|
|
255
255
|
email: hello@tristandunn.com
|
|
256
256
|
executables: []
|
|
@@ -275,7 +275,7 @@ files:
|
|
|
275
275
|
- features/step_definitions/event_steps.rb
|
|
276
276
|
- features/step_definitions/navigation_steps.rb
|
|
277
277
|
- features/step_definitions/presence_steps.rb
|
|
278
|
-
- features/support/application/public/javascripts/vendor/pusher-1.
|
|
278
|
+
- features/support/application/public/javascripts/vendor/pusher-1.12.5.js
|
|
279
279
|
- features/support/application/views/index.erb
|
|
280
280
|
- features/support/application.rb
|
|
281
281
|
- features/support/environment.rb
|
|
@@ -306,7 +306,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
306
306
|
version: '0'
|
|
307
307
|
segments:
|
|
308
308
|
- 0
|
|
309
|
-
hash:
|
|
309
|
+
hash: 2596033998219902442
|
|
310
310
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
311
311
|
none: false
|
|
312
312
|
requirements:
|
|
@@ -315,7 +315,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
315
315
|
version: '0'
|
|
316
316
|
segments:
|
|
317
317
|
- 0
|
|
318
|
-
hash:
|
|
318
|
+
hash: 2596033998219902442
|
|
319
319
|
requirements: []
|
|
320
320
|
rubyforge_project:
|
|
321
321
|
rubygems_version: 1.8.23
|
|
@@ -332,7 +332,7 @@ test_files:
|
|
|
332
332
|
- features/step_definitions/event_steps.rb
|
|
333
333
|
- features/step_definitions/navigation_steps.rb
|
|
334
334
|
- features/step_definitions/presence_steps.rb
|
|
335
|
-
- features/support/application/public/javascripts/vendor/pusher-1.
|
|
335
|
+
- features/support/application/public/javascripts/vendor/pusher-1.12.5.js
|
|
336
336
|
- features/support/application/views/index.erb
|
|
337
337
|
- features/support/application.rb
|
|
338
338
|
- features/support/environment.rb
|