pusher-fake 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/features/step_definitions/channel_steps.rb +2 -6
- data/features/step_definitions/event_steps.rb +13 -17
- data/features/support/application.rb +5 -7
- data/features/support/application/public/javascripts/vendor/pusher-1.11.js +107 -44
- data/features/support/environment.rb +0 -4
- data/lib/pusher-fake.rb +1 -1
- data/lib/pusher-fake/channel.rb +1 -1
- data/lib/pusher-fake/configuration.rb +4 -0
- data/lib/pusher-fake/server/application.rb +1 -1
- data/spec/lib/pusher-fake/configuration_spec.rb +1 -0
- data/spec/lib/pusher-fake/server/application_spec.rb +13 -0
- data/spec/spec_helper.rb +1 -0
- data/spec/support/have_configuration_option_matcher.rb +30 -14
- metadata +48 -37
@@ -16,11 +16,10 @@ end
|
|
16
16
|
When %{I subscribe to the "$channel" channel with presence events} do |channel|
|
17
17
|
page.execute_script(%{
|
18
18
|
var list = document.querySelector("#presence ul"),
|
19
|
+
count = document.querySelector("#presence header h1 span"),
|
19
20
|
channel = Pusher.instance.subscribe(#{channel.to_json});
|
20
21
|
|
21
22
|
channel.bind("pusher:subscription_succeeded", function(clients) {
|
22
|
-
var
|
23
|
-
count = document.querySelector("#presence header h1 span");
|
24
23
|
count.innerHTML = clients.count;
|
25
24
|
|
26
25
|
clients.each(function(client) {
|
@@ -30,8 +29,6 @@ When %{I subscribe to the "$channel" channel with presence events} do |channel|
|
|
30
29
|
});
|
31
30
|
});
|
32
31
|
channel.bind("pusher:member_added", function(client) {
|
33
|
-
var
|
34
|
-
count = document.querySelector("#presence header h1 span");
|
35
32
|
count.innerHTML = parseInt(count.innerHTML, 10) + 1;
|
36
33
|
|
37
34
|
var
|
@@ -39,8 +36,7 @@ When %{I subscribe to the "$channel" channel with presence events} do |channel|
|
|
39
36
|
element.setAttribute("id", "client-" + client.id);
|
40
37
|
});
|
41
38
|
channel.bind("pusher:member_removed", function(client) {
|
42
|
-
var item
|
43
|
-
count = document.querySelector("#presence header h1 span");
|
39
|
+
var item = list.querySelector("li#client-" + client.id);
|
44
40
|
|
45
41
|
count.innerHTML = parseInt(count.innerHTML, 10) - 1;
|
46
42
|
|
@@ -14,28 +14,24 @@ When %{I manually trigger the "$event" event on the "$channel" channel} do |even
|
|
14
14
|
page.execute_script(%{Pusher.instance.send_event(#{event.to_json}, {}, #{channel.to_json})})
|
15
15
|
end
|
16
16
|
|
17
|
-
Then /^
|
18
|
-
|
19
|
-
events = page.evaluate_script("Pusher.instance.events[#{[channel, event].join(":").to_json}]")
|
20
|
-
events.length.should == 1
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
Then /^I should not receive a "([^"]+)" event on the "([^"]+)" channel$/ do |event, channel|
|
25
|
-
wait do
|
26
|
-
events = page.evaluate_script("Pusher.instance.events[#{[channel, event].join(":").to_json}]")
|
27
|
-
events.should be_nil
|
28
|
-
end
|
29
|
-
end
|
17
|
+
Then /^([^ ]+) should receive a "([^"]+)" event on the "([^"]+)" channel$/ do |name, event, channel|
|
18
|
+
name = nil if name == "I"
|
30
19
|
|
31
|
-
Then /^([^I]+) should receive a "([^"]+)" event on the "([^"]+)" channel$/ do |name, event, channel|
|
32
20
|
using_session(name) do
|
33
|
-
|
21
|
+
wait do
|
22
|
+
events = page.evaluate_script("Pusher.instance.events[#{[channel, event].join(":").to_json}]")
|
23
|
+
events.length.should == 1
|
24
|
+
end
|
34
25
|
end
|
35
26
|
end
|
36
27
|
|
37
|
-
Then /^([^
|
28
|
+
Then /^([^ ]+) should not receive a "([^"]+)" event on the "([^"]+)" channel$/ do |name, event, channel|
|
29
|
+
name = nil if name == "I"
|
30
|
+
|
38
31
|
using_session(name) do
|
39
|
-
|
32
|
+
wait do
|
33
|
+
events = page.evaluate_script("Pusher.instance.events[#{[channel, event].join(":").to_json}]")
|
34
|
+
events.should be_nil
|
35
|
+
end
|
40
36
|
end
|
41
37
|
end
|
@@ -15,15 +15,13 @@ class Sinatra::Application
|
|
15
15
|
end
|
16
16
|
|
17
17
|
post "/pusher/auth" do
|
18
|
+
data = nil
|
18
19
|
channel = Pusher[params[:channel_name]]
|
19
20
|
|
20
|
-
if params[:channel_name] =~ /^
|
21
|
-
|
22
|
-
elsif params[:channel_name] =~ /^presence-/
|
23
|
-
channel.authenticate(params[:socket_id], {
|
24
|
-
user_id: params[:socket_id],
|
25
|
-
user_info: {}
|
26
|
-
}).to_json
|
21
|
+
if params[:channel_name] =~ /^presence-/
|
22
|
+
data = { user_id: params[:socket_id], user_info: {} }
|
27
23
|
end
|
24
|
+
|
25
|
+
channel.authenticate(params[:socket_id], data).to_json
|
28
26
|
end
|
29
27
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/*!
|
2
|
-
* Pusher JavaScript Library v1.11.
|
2
|
+
* Pusher JavaScript Library v1.11.2
|
3
3
|
* http://pusherapp.com/
|
4
4
|
*
|
5
5
|
* Copyright 2011, Pusher
|
@@ -181,7 +181,7 @@ Pusher.warn = function() {
|
|
181
181
|
};
|
182
182
|
|
183
183
|
// Pusher defaults
|
184
|
-
Pusher.VERSION = '1.11.
|
184
|
+
Pusher.VERSION = '1.11.2';
|
185
185
|
|
186
186
|
Pusher.host = 'ws.pusherapp.com';
|
187
187
|
Pusher.ws_port = 80;
|
@@ -307,6 +307,11 @@ Example:
|
|
307
307
|
var stateCallbacks = this.stateActions;
|
308
308
|
|
309
309
|
if (prevState && (Pusher.Util.arrayIndexOf(this.transitions[prevState], nextState) == -1)) {
|
310
|
+
this.emit('invalid_transition_attempt', {
|
311
|
+
oldState: prevState,
|
312
|
+
newState: nextState
|
313
|
+
});
|
314
|
+
|
310
315
|
throw new Error('Invalid transition [' + prevState + ' to ' + nextState + ']');
|
311
316
|
}
|
312
317
|
|
@@ -350,6 +355,7 @@ Example:
|
|
350
355
|
A little bauble to interface with window.navigator.onLine,
|
351
356
|
window.ononline and window.onoffline. Easier to mock.
|
352
357
|
*/
|
358
|
+
|
353
359
|
var NetInfo = function() {
|
354
360
|
var self = this;
|
355
361
|
Pusher.EventsDispatcher.call(this);
|
@@ -376,7 +382,7 @@ Example:
|
|
376
382
|
};
|
377
383
|
|
378
384
|
Pusher.Util.extend(NetInfo.prototype, Pusher.EventsDispatcher.prototype);
|
379
|
-
|
385
|
+
|
380
386
|
this.Pusher.NetInfo = NetInfo;
|
381
387
|
}).call(this);
|
382
388
|
|
@@ -431,7 +437,7 @@ Example:
|
|
431
437
|
this.netInfo.bind('online', function(){
|
432
438
|
if (self._machine.is('waiting')) {
|
433
439
|
self._machine.transition('connecting');
|
434
|
-
|
440
|
+
updateState('connecting');
|
435
441
|
}
|
436
442
|
});
|
437
443
|
|
@@ -452,8 +458,6 @@ Example:
|
|
452
458
|
|
453
459
|
// define the state machine that runs the connection
|
454
460
|
this._machine = new Pusher.Machine('initialized', machineTransitions, {
|
455
|
-
|
456
|
-
// TODO: Use the constructor for this.
|
457
461
|
initializedPre: function() {
|
458
462
|
self.compulsorySecure = self.options.encrypted;
|
459
463
|
|
@@ -469,16 +473,18 @@ Example:
|
|
469
473
|
self.emit('connecting_in', self.connectionWait);
|
470
474
|
}
|
471
475
|
|
472
|
-
if (self.netInfo.isOnLine()
|
473
|
-
|
476
|
+
if (self.netInfo.isOnLine() && self.connectionAttempts <= 4) {
|
477
|
+
updateState('connecting');
|
474
478
|
} else {
|
475
|
-
|
479
|
+
updateState('unavailable');
|
476
480
|
}
|
477
481
|
|
478
|
-
|
482
|
+
// When in the unavailable state we attempt to connect, but don't
|
483
|
+
// broadcast that fact
|
484
|
+
if (self.netInfo.isOnLine()) {
|
479
485
|
self._waitingTimer = setTimeout(function() {
|
480
486
|
self._machine.transition('connecting');
|
481
|
-
},
|
487
|
+
}, connectionDelay());
|
482
488
|
}
|
483
489
|
},
|
484
490
|
|
@@ -491,7 +497,7 @@ Example:
|
|
491
497
|
// state even when offline.
|
492
498
|
if (self.netInfo.isOnLine() === false) {
|
493
499
|
self._machine.transition('waiting');
|
494
|
-
|
500
|
+
updateState('unavailable');
|
495
501
|
|
496
502
|
return;
|
497
503
|
}
|
@@ -545,6 +551,11 @@ Example:
|
|
545
551
|
},
|
546
552
|
|
547
553
|
openToImpermanentlyClosing: function() {
|
554
|
+
// Possible to receive connection_established event after transition to impermanentlyClosing
|
555
|
+
// but before socket close. Prevent this triggering a transition from impermanentlyClosing to connected
|
556
|
+
// by unbinding onmessage callback.
|
557
|
+
self.socket.onmessage = undefined;
|
558
|
+
|
548
559
|
updateConnectionParameters();
|
549
560
|
},
|
550
561
|
|
@@ -556,17 +567,18 @@ Example:
|
|
556
567
|
self.socket.onclose = transitionToWaiting;
|
557
568
|
|
558
569
|
resetConnectionParameters(self);
|
570
|
+
self.connectedAt = new Date().getTime();
|
559
571
|
|
560
572
|
resetActivityCheck();
|
561
573
|
},
|
562
574
|
|
563
575
|
connectedPost: function() {
|
564
|
-
|
576
|
+
updateState('connected');
|
565
577
|
},
|
566
578
|
|
567
579
|
connectedExit: function() {
|
568
580
|
stopActivityCheck();
|
569
|
-
|
581
|
+
updateState('disconnected');
|
570
582
|
},
|
571
583
|
|
572
584
|
impermanentlyClosingPost: function() {
|
@@ -591,8 +603,12 @@ Example:
|
|
591
603
|
},
|
592
604
|
|
593
605
|
failedPre: function() {
|
594
|
-
|
606
|
+
updateState('failed');
|
595
607
|
Pusher.debug('WebSockets are not available in this browser.');
|
608
|
+
},
|
609
|
+
|
610
|
+
permanentlyClosedPost: function() {
|
611
|
+
updateState('disconnected');
|
596
612
|
}
|
597
613
|
});
|
598
614
|
|
@@ -633,7 +649,11 @@ Example:
|
|
633
649
|
protocol = 'wss://';
|
634
650
|
}
|
635
651
|
|
636
|
-
|
652
|
+
var flash = (Pusher.TransportType === "flash") ? "true" : "false";
|
653
|
+
|
654
|
+
return protocol + Pusher.host + ':' + port + '/app/' + key + '?protocol=5&client=js'
|
655
|
+
+ '&version=' + Pusher.VERSION
|
656
|
+
+ '&flash=' + flash;
|
637
657
|
}
|
638
658
|
|
639
659
|
// callback for close and retry. Used on timeouts.
|
@@ -657,6 +677,25 @@ Example:
|
|
657
677
|
if (self._activityTimer) { clearTimeout(self._activityTimer); }
|
658
678
|
}
|
659
679
|
|
680
|
+
// Returns the delay before the next connection attempt should be made
|
681
|
+
//
|
682
|
+
// This function guards against attempting to connect more frequently than
|
683
|
+
// once every second
|
684
|
+
//
|
685
|
+
function connectionDelay() {
|
686
|
+
var delay = self.connectionWait;
|
687
|
+
if (delay === 0) {
|
688
|
+
if (self.connectedAt) {
|
689
|
+
var t = 1000;
|
690
|
+
var connectedFor = new Date().getTime() - self.connectedAt;
|
691
|
+
if (connectedFor < t) {
|
692
|
+
delay = t - connectedFor;
|
693
|
+
}
|
694
|
+
}
|
695
|
+
}
|
696
|
+
return delay;
|
697
|
+
}
|
698
|
+
|
660
699
|
/*-----------------------------------------------
|
661
700
|
WebSocket Callbacks
|
662
701
|
-----------------------------------------------*/
|
@@ -666,28 +705,40 @@ Example:
|
|
666
705
|
self._machine.transition('open');
|
667
706
|
};
|
668
707
|
|
708
|
+
function handleCloseCode(code, message) {
|
709
|
+
// first inform the end-developer of this error
|
710
|
+
self.emit('error', {type: 'PusherError', data: {code: code, message: message}});
|
711
|
+
|
712
|
+
if (code === 4000) {
|
713
|
+
// SSL only app
|
714
|
+
self.compulsorySecure = true;
|
715
|
+
self.connectionSecure = true;
|
716
|
+
self.options.encrypted = true;
|
717
|
+
|
718
|
+
self._machine.transition('impermanentlyClosing')
|
719
|
+
} else if (code < 4100) {
|
720
|
+
// Permentently close connection
|
721
|
+
self._machine.transition('permanentlyClosing')
|
722
|
+
} else if (code < 4200) {
|
723
|
+
// Backoff before reconnecting
|
724
|
+
self.connectionWait = 1000;
|
725
|
+
self._machine.transition('waiting')
|
726
|
+
} else if (code < 4300) {
|
727
|
+
// Reconnect immediately
|
728
|
+
self._machine.transition('impermanentlyClosing')
|
729
|
+
} else {
|
730
|
+
// Unknown error
|
731
|
+
self._machine.transition('permanentlyClosing')
|
732
|
+
}
|
733
|
+
}
|
734
|
+
|
669
735
|
function ws_onMessageOpen(event) {
|
670
736
|
var params = parseWebSocketEvent(event);
|
671
737
|
if (params !== undefined) {
|
672
738
|
if (params.event === 'pusher:connection_established') {
|
673
739
|
self._machine.transition('connected', params.data.socket_id);
|
674
740
|
} else if (params.event === 'pusher:error') {
|
675
|
-
|
676
|
-
self.emit('error', {type: 'PusherError', data: params.data});
|
677
|
-
|
678
|
-
switch (params.data.code) {
|
679
|
-
case 4000:
|
680
|
-
Pusher.warn(params.data.message);
|
681
|
-
|
682
|
-
self.compulsorySecure = true;
|
683
|
-
self.connectionSecure = true;
|
684
|
-
self.options.encrypted = true;
|
685
|
-
break;
|
686
|
-
case 4001:
|
687
|
-
// App not found by key - close connection
|
688
|
-
self._machine.transition('permanentlyClosing');
|
689
|
-
break;
|
690
|
-
}
|
741
|
+
handleCloseCode(params.data.code, params.data.message)
|
691
742
|
}
|
692
743
|
}
|
693
744
|
}
|
@@ -753,19 +804,21 @@ Example:
|
|
753
804
|
self._machine.transition('impermanentlyClosing');
|
754
805
|
}
|
755
806
|
|
756
|
-
|
757
|
-
|
758
|
-
|
759
|
-
|
760
|
-
|
807
|
+
// Updates the public state information exposed by connection
|
808
|
+
//
|
809
|
+
// This is distinct from the internal state information used by _machine
|
810
|
+
// to manage the connection
|
811
|
+
//
|
812
|
+
function updateState(newState, data) {
|
761
813
|
var prevState = self.state;
|
762
|
-
|
763
814
|
self.state = newState;
|
764
815
|
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
816
|
+
// Only emit when the state changes
|
817
|
+
if (prevState !== newState) {
|
818
|
+
Pusher.debug('State changed', prevState + ' -> ' + newState);
|
819
|
+
self.emit('state_change', {previous: prevState, current: newState});
|
820
|
+
self.emit(newState, data);
|
821
|
+
}
|
769
822
|
}
|
770
823
|
};
|
771
824
|
|
@@ -785,14 +838,24 @@ Example:
|
|
785
838
|
}
|
786
839
|
// user re-opening connection after closing it
|
787
840
|
else if(this._machine.is("permanentlyClosed")) {
|
841
|
+
resetConnectionParameters(this);
|
788
842
|
this._machine.transition('waiting');
|
789
843
|
}
|
790
844
|
};
|
791
845
|
|
792
846
|
Connection.prototype.send = function(data) {
|
793
847
|
if (this._machine.is('connected')) {
|
794
|
-
|
795
|
-
|
848
|
+
// Bug in iOS (reproduced in 5.0.1) Mobile Safari:
|
849
|
+
// 1. Open page/tab, connect WS, get some data.
|
850
|
+
// 2. Switch tab or close Mobile Safari and wait for WS connection to get closed (probably by server).
|
851
|
+
// 3. Switch back to tab or open Mobile Safari and Mobile Safari crashes.
|
852
|
+
// The problem is that WS tries to send data on closed WS connection before it realises it is closed.
|
853
|
+
// The timeout means that by the time the send happens, the WS readyState correctly reflects closed state.
|
854
|
+
var self = this;
|
855
|
+
setTimeout(function() {
|
856
|
+
self.socket.send(data);
|
857
|
+
}, 0);
|
858
|
+
return true; // only a reflection of fact that WS thinks it is open - could get returned before some lower-level failure.
|
796
859
|
} else {
|
797
860
|
return false;
|
798
861
|
}
|
data/lib/pusher-fake.rb
CHANGED
data/lib/pusher-fake/channel.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
module PusherFake
|
2
2
|
class Configuration
|
3
|
+
# @return [String] The Pusher Applicaiton ID. (Defaults to +PUSHER_APP_ID+.)
|
4
|
+
attr_accessor :app_id
|
5
|
+
|
3
6
|
# @return [String] The Pusher API key. (Defaults to +PUSHER_API_KEY+.)
|
4
7
|
attr_accessor :key
|
5
8
|
|
@@ -20,6 +23,7 @@ module PusherFake
|
|
20
23
|
|
21
24
|
# Instantiated from {PusherFake.configuration}. Sets the defaults.
|
22
25
|
def initialize
|
26
|
+
self.app_id = "PUSHER_APP_ID"
|
23
27
|
self.key = "PUSHER_API_KEY"
|
24
28
|
self.secret = "PUSHER_API_SECRET"
|
25
29
|
self.socket_host = "127.0.0.1"
|
@@ -18,7 +18,7 @@ module PusherFake
|
|
18
18
|
#
|
19
19
|
# @return [String] The channel name.
|
20
20
|
def self.channel
|
21
|
-
path.match(%r{/apps/
|
21
|
+
path.match(%r{/apps/#{PusherFake.configuration.app_id}/channels/(.+)/events}i)[1]
|
22
22
|
end
|
23
23
|
|
24
24
|
# Parse and return the event data from the request JSON.
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe PusherFake::Configuration do
|
4
|
+
it { should have_configuration_option(:app_id).with_default("PUSHER_APP_ID") }
|
4
5
|
it { should have_configuration_option(:key).with_default("PUSHER_API_KEY") }
|
5
6
|
it { should have_configuration_option(:secret).with_default("PUSHER_API_SECRET") }
|
6
7
|
it { should have_configuration_option(:socket_host).with_default("127.0.0.1") }
|
@@ -60,6 +60,19 @@ describe PusherFake::Server::Application, ".channel" do
|
|
60
60
|
it "returns the channel name from the path" do
|
61
61
|
subject.channel.should == channel
|
62
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
|
63
76
|
end
|
64
77
|
|
65
78
|
describe PusherFake::Server::Application, ".data" do
|
data/spec/spec_helper.rb
CHANGED
@@ -1,19 +1,35 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
1
|
+
module BartenderHelper
|
2
|
+
class ConfigurationOption
|
3
|
+
def initialize(option)
|
4
|
+
@option = option
|
5
|
+
end
|
6
|
+
|
7
|
+
def matches?(configuration)
|
8
|
+
@configuration = configuration
|
9
|
+
|
10
|
+
@configuration.respond_to?(@option).should == true
|
11
|
+
|
12
|
+
@configuration.__send__(@option).should == @default if instance_variables.include?("@default")
|
13
|
+
|
14
|
+
@configuration.__send__(:"#{@option}=", "value")
|
15
|
+
@configuration.__send__(@option).should == "value"
|
16
|
+
end
|
17
|
+
|
18
|
+
def with_default(default)
|
19
|
+
@default = default
|
20
|
+
|
21
|
+
self
|
22
|
+
end
|
8
23
|
|
9
|
-
|
10
|
-
|
24
|
+
def failure_message
|
25
|
+
description = "expected #{@configuration} to have"
|
26
|
+
description << " configuration option #{@option.inspect}"
|
27
|
+
description << " with a default of #{@default.inspect}" if instance_variables.include?("@default")
|
28
|
+
description
|
29
|
+
end
|
11
30
|
end
|
12
31
|
|
13
|
-
|
14
|
-
|
15
|
-
description << " configuration option #{option.inspect}"
|
16
|
-
description << " with a default of #{@default.inspect}" if defined?(@default)
|
17
|
-
description
|
32
|
+
def have_configuration_option(option)
|
33
|
+
ConfigurationOption.new(option)
|
18
34
|
end
|
19
35
|
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.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-03-
|
12
|
+
date: 2012-03-29 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: em-websocket
|
16
|
-
requirement: &
|
16
|
+
requirement: &70195226755160 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - =
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 0.3.6
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70195226755160
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: ruby-hmac
|
27
|
-
requirement: &
|
27
|
+
requirement: &70195226768900 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - =
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: 0.4.0
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70195226768900
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: thin
|
38
|
-
requirement: &
|
38
|
+
requirement: &70195226779500 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - =
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: 1.3.1
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70195226779500
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: yajl-ruby
|
49
|
-
requirement: &
|
49
|
+
requirement: &70195226774260 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - =
|
@@ -54,32 +54,32 @@ dependencies:
|
|
54
54
|
version: 1.1.0
|
55
55
|
type: :runtime
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *70195226774260
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: bourne
|
60
|
-
requirement: &
|
60
|
+
requirement: &70195226798680 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - =
|
64
64
|
- !ruby/object:Gem::Version
|
65
|
-
version: 1.1.
|
65
|
+
version: 1.1.2
|
66
66
|
type: :development
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *70195226798680
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: bundler
|
71
|
-
requirement: &
|
71
|
+
requirement: &70195226812420 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
|
-
- -
|
74
|
+
- - ! '>='
|
75
75
|
- !ruby/object:Gem::Version
|
76
76
|
version: 1.1.0
|
77
77
|
type: :development
|
78
78
|
prerelease: false
|
79
|
-
version_requirements: *
|
79
|
+
version_requirements: *70195226812420
|
80
80
|
- !ruby/object:Gem::Dependency
|
81
81
|
name: capybara
|
82
|
-
requirement: &
|
82
|
+
requirement: &70195226808740 !ruby/object:Gem::Requirement
|
83
83
|
none: false
|
84
84
|
requirements:
|
85
85
|
- - =
|
@@ -87,21 +87,21 @@ dependencies:
|
|
87
87
|
version: 1.1.2
|
88
88
|
type: :development
|
89
89
|
prerelease: false
|
90
|
-
version_requirements: *
|
90
|
+
version_requirements: *70195226808740
|
91
91
|
- !ruby/object:Gem::Dependency
|
92
92
|
name: capybara-webkit
|
93
|
-
requirement: &
|
93
|
+
requirement: &70195226819740 !ruby/object:Gem::Requirement
|
94
94
|
none: false
|
95
95
|
requirements:
|
96
96
|
- - =
|
97
97
|
- !ruby/object:Gem::Version
|
98
|
-
version: 0.
|
98
|
+
version: 0.11.0
|
99
99
|
type: :development
|
100
100
|
prerelease: false
|
101
|
-
version_requirements: *
|
101
|
+
version_requirements: *70195226819740
|
102
102
|
- !ruby/object:Gem::Dependency
|
103
103
|
name: cucumber
|
104
|
-
requirement: &
|
104
|
+
requirement: &70195226816180 !ruby/object:Gem::Requirement
|
105
105
|
none: false
|
106
106
|
requirements:
|
107
107
|
- - =
|
@@ -109,10 +109,10 @@ dependencies:
|
|
109
109
|
version: 1.1.9
|
110
110
|
type: :development
|
111
111
|
prerelease: false
|
112
|
-
version_requirements: *
|
112
|
+
version_requirements: *70195226816180
|
113
113
|
- !ruby/object:Gem::Dependency
|
114
114
|
name: pusher
|
115
|
-
requirement: &
|
115
|
+
requirement: &70195226828020 !ruby/object:Gem::Requirement
|
116
116
|
none: false
|
117
117
|
requirements:
|
118
118
|
- - =
|
@@ -120,32 +120,43 @@ dependencies:
|
|
120
120
|
version: 0.9.2
|
121
121
|
type: :development
|
122
122
|
prerelease: false
|
123
|
-
version_requirements: *
|
123
|
+
version_requirements: *70195226828020
|
124
|
+
- !ruby/object:Gem::Dependency
|
125
|
+
name: rake
|
126
|
+
requirement: &70195226824580 !ruby/object:Gem::Requirement
|
127
|
+
none: false
|
128
|
+
requirements:
|
129
|
+
- - =
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: 0.9.2.2
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: *70195226824580
|
124
135
|
- !ruby/object:Gem::Dependency
|
125
136
|
name: redcarpet
|
126
|
-
requirement: &
|
137
|
+
requirement: &70195226822700 !ruby/object:Gem::Requirement
|
127
138
|
none: false
|
128
139
|
requirements:
|
129
140
|
- - =
|
130
141
|
- !ruby/object:Gem::Version
|
131
|
-
version: 2.1.
|
142
|
+
version: 2.1.1
|
132
143
|
type: :development
|
133
144
|
prerelease: false
|
134
|
-
version_requirements: *
|
145
|
+
version_requirements: *70195226822700
|
135
146
|
- !ruby/object:Gem::Dependency
|
136
147
|
name: rspec
|
137
|
-
requirement: &
|
148
|
+
requirement: &70195230220940 !ruby/object:Gem::Requirement
|
138
149
|
none: false
|
139
150
|
requirements:
|
140
151
|
- - =
|
141
152
|
- !ruby/object:Gem::Version
|
142
|
-
version: 2.
|
153
|
+
version: 2.9.0
|
143
154
|
type: :development
|
144
155
|
prerelease: false
|
145
|
-
version_requirements: *
|
156
|
+
version_requirements: *70195230220940
|
146
157
|
- !ruby/object:Gem::Dependency
|
147
158
|
name: sinatra
|
148
|
-
requirement: &
|
159
|
+
requirement: &70195230219480 !ruby/object:Gem::Requirement
|
149
160
|
none: false
|
150
161
|
requirements:
|
151
162
|
- - =
|
@@ -153,10 +164,10 @@ dependencies:
|
|
153
164
|
version: 1.3.2
|
154
165
|
type: :development
|
155
166
|
prerelease: false
|
156
|
-
version_requirements: *
|
167
|
+
version_requirements: *70195230219480
|
157
168
|
- !ruby/object:Gem::Dependency
|
158
169
|
name: yard
|
159
|
-
requirement: &
|
170
|
+
requirement: &70195230217620 !ruby/object:Gem::Requirement
|
160
171
|
none: false
|
161
172
|
requirements:
|
162
173
|
- - =
|
@@ -164,7 +175,7 @@ dependencies:
|
|
164
175
|
version: 0.7.5
|
165
176
|
type: :development
|
166
177
|
prerelease: false
|
167
|
-
version_requirements: *
|
178
|
+
version_requirements: *70195230217620
|
168
179
|
description: A fake Pusher server for development and testing.
|
169
180
|
email: hello@tristandunn.com
|
170
181
|
executables: []
|
@@ -220,7 +231,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
220
231
|
version: '0'
|
221
232
|
segments:
|
222
233
|
- 0
|
223
|
-
hash:
|
234
|
+
hash: 1138384851111270143
|
224
235
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
225
236
|
none: false
|
226
237
|
requirements:
|
@@ -229,7 +240,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
229
240
|
version: '0'
|
230
241
|
segments:
|
231
242
|
- 0
|
232
|
-
hash:
|
243
|
+
hash: 1138384851111270143
|
233
244
|
requirements: []
|
234
245
|
rubyforge_project:
|
235
246
|
rubygems_version: 1.8.11
|