faye 0.8.8 → 0.8.9
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of faye might be problematic. Click here for more details.
- data/History.txt +16 -10
- data/README.rdoc +1 -1
- data/lib/faye-browser-min.js +1 -1
- data/lib/faye-browser-min.js.map +2 -2
- data/lib/faye-browser.js +302 -287
- data/lib/faye.rb +21 -21
- data/lib/faye/adapters/rack_adapter.rb +50 -48
- data/lib/faye/adapters/static_server.rb +22 -22
- data/lib/faye/engines/connection.rb +13 -13
- data/lib/faye/engines/memory.rb +21 -21
- data/lib/faye/engines/proxy.rb +23 -23
- data/lib/faye/error.rb +6 -6
- data/lib/faye/mixins/logging.rb +12 -12
- data/lib/faye/mixins/publisher.rb +6 -6
- data/lib/faye/mixins/timeouts.rb +1 -1
- data/lib/faye/protocol/channel.rb +24 -24
- data/lib/faye/protocol/client.rb +71 -73
- data/lib/faye/protocol/extensible.rb +7 -7
- data/lib/faye/protocol/grammar.rb +13 -13
- data/lib/faye/protocol/server.rb +57 -57
- data/lib/faye/protocol/socket.rb +4 -4
- data/lib/faye/protocol/subscription.rb +4 -4
- data/lib/faye/transport/http.rb +13 -13
- data/lib/faye/transport/local.rb +5 -5
- data/lib/faye/transport/transport.rb +25 -25
- data/lib/faye/transport/web_socket.rb +34 -30
- data/lib/faye/util/namespace.rb +4 -4
- data/spec/browser.html +5 -5
- data/spec/javascript/channel_spec.js +3 -3
- data/spec/javascript/client_spec.js +104 -98
- data/spec/javascript/engine/memory_spec.js +1 -1
- data/spec/javascript/engine_spec.js +70 -70
- data/spec/javascript/faye_spec.js +6 -6
- data/spec/javascript/grammar_spec.js +12 -12
- data/spec/javascript/node_adapter_spec.js +46 -46
- data/spec/javascript/publisher_spec.js +4 -4
- data/spec/javascript/server/connect_spec.js +21 -21
- data/spec/javascript/server/disconnect_spec.js +15 -15
- data/spec/javascript/server/extensions_spec.js +6 -6
- data/spec/javascript/server/handshake_spec.js +18 -18
- data/spec/javascript/server/integration_spec.js +23 -23
- data/spec/javascript/server/publish_spec.js +9 -9
- data/spec/javascript/server/subscribe_spec.js +30 -30
- data/spec/javascript/server/unsubscribe_spec.js +30 -30
- data/spec/javascript/server_spec.js +15 -15
- data/spec/javascript/transport_spec.js +32 -27
- data/spec/node.js +2 -2
- data/spec/ruby/channel_spec.rb +2 -2
- data/spec/ruby/client_spec.rb +100 -92
- data/spec/ruby/engine_examples.rb +51 -51
- data/spec/ruby/faye_spec.rb +5 -5
- data/spec/ruby/grammar_spec.rb +12 -12
- data/spec/ruby/publisher_spec.rb +4 -4
- data/spec/ruby/rack_adapter_spec.rb +34 -34
- data/spec/ruby/server/connect_spec.rb +22 -22
- data/spec/ruby/server/disconnect_spec.rb +16 -16
- data/spec/ruby/server/extensions_spec.rb +8 -8
- data/spec/ruby/server/handshake_spec.rb +20 -20
- data/spec/ruby/server/integration_spec.rb +22 -24
- data/spec/ruby/server/publish_spec.rb +9 -9
- data/spec/ruby/server/subscribe_spec.rb +31 -31
- data/spec/ruby/server/unsubscribe_spec.rb +31 -31
- data/spec/ruby/server_spec.rb +17 -17
- data/spec/ruby/transport_spec.rb +23 -23
- data/spec/testswarm +23 -10
- data/spec/thin_proxy.rb +5 -5
- metadata +90 -59
@@ -4,7 +4,7 @@ JS.ENV.ServerSpec = JS.Test.describe("Server", function() { with(this) {
|
|
4
4
|
stub(Faye.Engine, "get").returns(engine)
|
5
5
|
this.server = new Faye.Server()
|
6
6
|
}})
|
7
|
-
|
7
|
+
|
8
8
|
describe("#process", function() { with(this) {
|
9
9
|
before(function() { with(this) {
|
10
10
|
this.handshake = {channel: "/meta/handshake", data: "handshake"}
|
@@ -13,17 +13,17 @@ JS.ENV.ServerSpec = JS.Test.describe("Server", function() { with(this) {
|
|
13
13
|
this.subscribe = {channel: "/meta/subscribe", data: "subscribe"}
|
14
14
|
this.unsubscribe = {channel: "/meta/unsubscribe", data: "unsubscribe"}
|
15
15
|
this.publish = {channel: "/some/channel", data: "publish"}
|
16
|
-
|
16
|
+
|
17
17
|
stub(engine, "interval", 0)
|
18
18
|
stub(engine, "timeout", 60)
|
19
19
|
}})
|
20
|
-
|
20
|
+
|
21
21
|
it("returns an empty response for no messages", function() { with(this) {
|
22
22
|
var response = null
|
23
23
|
server.process([], false, function(r) { response = r})
|
24
24
|
assertEqual( [], response )
|
25
25
|
}})
|
26
|
-
|
26
|
+
|
27
27
|
it("ignores invalid messages", function() { with(this) {
|
28
28
|
var response = null
|
29
29
|
server.process([{}, {channel: "invalid"}], false, function(r) { response = r})
|
@@ -48,19 +48,19 @@ JS.ENV.ServerSpec = JS.Test.describe("Server", function() { with(this) {
|
|
48
48
|
}
|
49
49
|
], response)
|
50
50
|
}})
|
51
|
-
|
51
|
+
|
52
52
|
it("routes single messages to appropriate handlers", function() { with(this) {
|
53
53
|
expect(server, "handshake").given(handshake, false).yielding([{}])
|
54
54
|
server.process(handshake, false, function() {})
|
55
55
|
}})
|
56
|
-
|
56
|
+
|
57
57
|
it("routes a list of messages to appropriate handlers", function() { with(this) {
|
58
58
|
expect(server, "handshake").given(handshake, false).yielding([{}])
|
59
59
|
expect(server, "connect").given(connect, false).yielding([{}])
|
60
60
|
expect(server, "disconnect").given(disconnect, false).yielding([{}])
|
61
61
|
expect(server, "subscribe").given(subscribe, false).yielding([{}])
|
62
62
|
expect(server, "unsubscribe").given(unsubscribe, false).yielding([{}])
|
63
|
-
|
63
|
+
|
64
64
|
expect(engine, "publish").given(handshake).exactly(0)
|
65
65
|
expect(engine, "publish").given(connect).exactly(0)
|
66
66
|
expect(engine, "publish").given(disconnect).exactly(0)
|
@@ -68,15 +68,15 @@ JS.ENV.ServerSpec = JS.Test.describe("Server", function() { with(this) {
|
|
68
68
|
expect(engine, "publish").given(unsubscribe).exactly(0)
|
69
69
|
|
70
70
|
expect(engine, "publish").given(publish)
|
71
|
-
|
71
|
+
|
72
72
|
server.process([handshake, connect, disconnect, subscribe, unsubscribe, publish], false, function() {})
|
73
73
|
}})
|
74
|
-
|
74
|
+
|
75
75
|
describe("handshaking", function() { with(this) {
|
76
76
|
before(function() { with(this) {
|
77
77
|
expect(server, "handshake").given(handshake, false).yielding([{channel: "/meta/handshake", successful: true}])
|
78
78
|
}})
|
79
|
-
|
79
|
+
|
80
80
|
it("returns the handshake response with advice", function() { with(this) {
|
81
81
|
server.process(handshake, false, function(response) {
|
82
82
|
assertEqual([
|
@@ -88,13 +88,13 @@ JS.ENV.ServerSpec = JS.Test.describe("Server", function() { with(this) {
|
|
88
88
|
})
|
89
89
|
}})
|
90
90
|
}})
|
91
|
-
|
91
|
+
|
92
92
|
describe("connecting for messages", function() { with(this) {
|
93
93
|
before(function() { with(this) {
|
94
94
|
this.messages = [{channel: "/a"}, {channel: "/b"}]
|
95
95
|
expect(server, "connect").given(connect, false).yielding([messages])
|
96
96
|
}})
|
97
|
-
|
97
|
+
|
98
98
|
it("returns the new messages", function() { with(this) {
|
99
99
|
server.process(connect, false, function(response) {
|
100
100
|
assertEqual( messages, response )
|
@@ -102,17 +102,17 @@ JS.ENV.ServerSpec = JS.Test.describe("Server", function() { with(this) {
|
|
102
102
|
}})
|
103
103
|
}})
|
104
104
|
}})
|
105
|
-
|
105
|
+
|
106
106
|
describe("#flushConnection", function() { with(this) {
|
107
107
|
before(function() { with(this) {
|
108
108
|
this.message = {clientId: "fakeclientid"}
|
109
109
|
}})
|
110
|
-
|
110
|
+
|
111
111
|
it("flushes the connection when given one message", function() { with(this) {
|
112
112
|
expect(engine, "flush").given("fakeclientid")
|
113
113
|
server.flushConnection(message)
|
114
114
|
}})
|
115
|
-
|
115
|
+
|
116
116
|
it("flushes the connection when given a list of messages", function() { with(this) {
|
117
117
|
expect(engine, "flush").given("fakeclientid")
|
118
118
|
server.flushConnection([message])
|
@@ -1,7 +1,12 @@
|
|
1
1
|
JS.ENV.TransportSpec = JS.Test.describe("Transport", function() { with(this) {
|
2
2
|
before(function() { with(this) {
|
3
|
-
this.client = {
|
4
|
-
|
3
|
+
this.client = {
|
4
|
+
endpoint: "http://example.com/",
|
5
|
+
endpoints: {},
|
6
|
+
transports: {},
|
7
|
+
getClientId: function() {}
|
8
|
+
}
|
9
|
+
|
5
10
|
if (Faye.Transport.NodeLocal) {
|
6
11
|
this.LocalTransport = Faye.Transport.NodeLocal
|
7
12
|
this.HttpTransport = Faye.Transport.NodeHttp
|
@@ -14,113 +19,113 @@ JS.ENV.TransportSpec = JS.Test.describe("Transport", function() { with(this) {
|
|
14
19
|
this.longPolling = "long-polling"
|
15
20
|
}
|
16
21
|
}})
|
17
|
-
|
22
|
+
|
18
23
|
describe("get", function() { with(this) {
|
19
24
|
before(function() { with(this) {
|
20
25
|
stub(HttpTransport, "isUsable").yields([false])
|
21
26
|
stub(LocalTransport, "isUsable").yields([false])
|
22
27
|
}})
|
23
|
-
|
28
|
+
|
24
29
|
describe("when no transport is usable", function() { with(this) {
|
25
30
|
it("raises an exception", function() { with(this) {
|
26
|
-
assertThrows(Error, function() { Faye.Transport.get(client, [longPolling, inProcess]) })
|
31
|
+
assertThrows(Error, function() { Faye.Transport.get(client, [longPolling, inProcess], []) })
|
27
32
|
}})
|
28
33
|
}})
|
29
|
-
|
34
|
+
|
30
35
|
describe("when a less preferred transport is usable", function() { with(this) {
|
31
36
|
before(function() { with(this) {
|
32
37
|
stub(HttpTransport, "isUsable").yields([true])
|
33
38
|
}})
|
34
|
-
|
39
|
+
|
35
40
|
it("returns a transport of the usable type", function() { with(this) {
|
36
|
-
Faye.Transport.get(client, [longPolling, inProcess], function(transport) {
|
41
|
+
Faye.Transport.get(client, [longPolling, inProcess], [], function(transport) {
|
37
42
|
assertKindOf( HttpTransport, transport )
|
38
43
|
})
|
39
44
|
}})
|
40
|
-
|
45
|
+
|
41
46
|
it("raises an exception if the usable type is not requested", function() { with(this) {
|
42
|
-
assertThrows(Error, function() { Faye.Transport.get(client, [inProcess]) })
|
47
|
+
assertThrows(Error, function() { Faye.Transport.get(client, [inProcess], []) })
|
43
48
|
}})
|
44
|
-
|
49
|
+
|
45
50
|
it("allows the usable type to be specifically selected", function() { with(this) {
|
46
|
-
Faye.Transport.get(client, [longPolling], function(transport) {
|
51
|
+
Faye.Transport.get(client, [longPolling], [], function(transport) {
|
47
52
|
assertKindOf( HttpTransport, transport )
|
48
53
|
})
|
49
54
|
}})
|
50
55
|
}})
|
51
|
-
|
56
|
+
|
52
57
|
describe("when all transports are usable", function() { with(this) {
|
53
58
|
before(function() { with(this) {
|
54
59
|
stub(LocalTransport, "isUsable").yields([true])
|
55
60
|
stub(HttpTransport, "isUsable").yields([true])
|
56
61
|
}})
|
57
|
-
|
62
|
+
|
58
63
|
it("returns the most preferred type", function() { with(this) {
|
59
|
-
Faye.Transport.get(client, [longPolling, inProcess], function(transport) {
|
64
|
+
Faye.Transport.get(client, [longPolling, inProcess], [], function(transport) {
|
60
65
|
assertKindOf( LocalTransport, transport )
|
61
66
|
})
|
62
67
|
}})
|
63
|
-
|
68
|
+
|
64
69
|
it("allows types to be specifically selected", function() { with(this) {
|
65
|
-
Faye.Transport.get(client, [inProcess], function(transport) {
|
70
|
+
Faye.Transport.get(client, [inProcess], [], function(transport) {
|
66
71
|
assertKindOf( LocalTransport, transport )
|
67
72
|
})
|
68
|
-
Faye.Transport.get(client, [longPolling], function(transport) {
|
73
|
+
Faye.Transport.get(client, [longPolling], [], function(transport) {
|
69
74
|
assertKindOf( HttpTransport, transport )
|
70
75
|
})
|
71
76
|
}})
|
72
77
|
}})
|
73
78
|
}})
|
74
|
-
|
79
|
+
|
75
80
|
describe("send", function() { with(this) {
|
76
81
|
include(JS.Test.FakeClock)
|
77
82
|
before(function() { this.clock.stub() })
|
78
83
|
after(function() { this.clock.reset() })
|
79
|
-
|
84
|
+
|
80
85
|
describe("for batching transports", function() { with(this) {
|
81
86
|
before(function() { with(this) {
|
82
87
|
this.Transport = Faye.Class(Faye.Transport, {batching: true})
|
83
88
|
this.transport = new Transport(client)
|
84
89
|
}})
|
85
|
-
|
90
|
+
|
86
91
|
it("does not make an immediate request", function() { with(this) {
|
87
92
|
expect(transport, "request").exactly(0)
|
88
93
|
transport.send({batch: "me"}, 60)
|
89
94
|
}})
|
90
|
-
|
95
|
+
|
91
96
|
it("queues the message to be sent after a timeout", function() { with(this) {
|
92
97
|
expect(transport, "request").given([{batch: "me"}], 60)
|
93
98
|
transport.send({batch: "me"}, 60)
|
94
99
|
clock.tick(10)
|
95
100
|
}})
|
96
|
-
|
101
|
+
|
97
102
|
it("allows multiple messages to be batched together", function() { with(this) {
|
98
103
|
expect(transport, "request").given([{id: 1}, {id: 2}], 60)
|
99
104
|
transport.send({id: 1}, 60)
|
100
105
|
transport.send({id: 2}, 60)
|
101
106
|
clock.tick(10)
|
102
107
|
}})
|
103
|
-
|
108
|
+
|
104
109
|
it("adds advice to connect messages sent with others", function() { with(this) {
|
105
110
|
expect(transport, "request").given([{channel: "/meta/connect", advice: {timeout: 0}}, {}], 60)
|
106
111
|
transport.send({channel: "/meta/connect"}, 60)
|
107
112
|
transport.send({}, 60)
|
108
113
|
clock.tick(10)
|
109
114
|
}})
|
110
|
-
|
115
|
+
|
111
116
|
it("adds no advice to connect messages sent alone", function() { with(this) {
|
112
117
|
expect(transport, "request").given([{channel: "/meta/connect"}], 60)
|
113
118
|
transport.send({channel: "/meta/connect"}, 60)
|
114
119
|
clock.tick(10)
|
115
120
|
}})
|
116
121
|
}})
|
117
|
-
|
122
|
+
|
118
123
|
describe("for non-batching transports", function() { with(this) {
|
119
124
|
before(function() { with(this) {
|
120
125
|
this.Transport = Faye.Class(Faye.Transport, {batching: false})
|
121
126
|
this.transport = new Transport(client)
|
122
127
|
}})
|
123
|
-
|
128
|
+
|
124
129
|
it("makes a request immediately", function() { with(this) {
|
125
130
|
expect(transport, "request").given([{no: "batch"}], 60)
|
126
131
|
transport.send({no: "batch"}, 60)
|
data/spec/node.js
CHANGED
@@ -29,10 +29,10 @@ JS.require('Faye', 'JS.Test', 'JS.Range', function() {
|
|
29
29
|
return function(actual) { testcase.assertEqual(expected, actual) }
|
30
30
|
}
|
31
31
|
})
|
32
|
-
|
32
|
+
|
33
33
|
JS.ENV.Engine = {}
|
34
34
|
JS.ENV.Server = {}
|
35
|
-
|
35
|
+
|
36
36
|
JS.require( 'FayeSpec',
|
37
37
|
'GrammarSpec',
|
38
38
|
'PublisherSpec',
|
data/spec/ruby/channel_spec.rb
CHANGED
@@ -5,10 +5,10 @@ describe Faye::Channel do
|
|
5
5
|
it "returns all patterns that match a channel" do
|
6
6
|
Faye::Channel.expand("/foo").should == [
|
7
7
|
"/**", "/foo", "/*"]
|
8
|
-
|
8
|
+
|
9
9
|
Faye::Channel.expand("/foo/bar").should == [
|
10
10
|
"/**", "/foo/bar", "/foo/*", "/foo/**"]
|
11
|
-
|
11
|
+
|
12
12
|
Faye::Channel.expand("/foo/bar/qux").should == [
|
13
13
|
"/**", "/foo/bar/qux", "/foo/bar/*", "/foo/**", "/foo/bar/**"]
|
14
14
|
end
|
data/spec/ruby/client_spec.rb
CHANGED
@@ -8,9 +8,9 @@ describe Faye::Client do
|
|
8
8
|
transport.extend(Faye::Publisher)
|
9
9
|
transport
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
before { EM.stub(:add_timer) }
|
13
|
-
|
13
|
+
|
14
14
|
def stub_response(response)
|
15
15
|
transport.stub(:send) do |message, *args|
|
16
16
|
response["id"] = message["id"]
|
@@ -22,7 +22,7 @@ describe Faye::Client do
|
|
22
22
|
Faye::Transport.stub(:get).and_yield(transport)
|
23
23
|
@client = Faye::Client.new("http://localhost/")
|
24
24
|
end
|
25
|
-
|
25
|
+
|
26
26
|
def create_connected_client
|
27
27
|
create_client
|
28
28
|
stub_response "channel" => "/meta/handshake",
|
@@ -30,29 +30,22 @@ describe Faye::Client do
|
|
30
30
|
"version" => "1.0",
|
31
31
|
"supportedConnectionTypes" => ["websocket"],
|
32
32
|
"clientId" => "fakeid"
|
33
|
-
|
33
|
+
|
34
34
|
@client.handshake
|
35
35
|
end
|
36
|
-
|
36
|
+
|
37
37
|
def subscribe(client, channel, callback = nil)
|
38
38
|
stub_response "channel" => "/meta/subscribe",
|
39
39
|
"successful" => true,
|
40
40
|
"clientId" => "fakeid",
|
41
41
|
"subscription" => channel
|
42
|
-
|
42
|
+
|
43
43
|
@subs_called = 0
|
44
44
|
callback ||= lambda { |m| @subs_called = 1 }
|
45
45
|
@client.subscribe(channel, &callback)
|
46
46
|
end
|
47
47
|
|
48
48
|
describe :initialize do
|
49
|
-
it "creates a transport the server must support" do
|
50
|
-
Faye::Transport.should_receive(:get).with(instance_of(Faye::Client),
|
51
|
-
["long-polling", "callback-polling", "in-process"]).
|
52
|
-
and_return(transport)
|
53
|
-
Faye::Client.new("http://localhost/")
|
54
|
-
end
|
55
|
-
|
56
49
|
it "puts the client in the UNCONNECTED state" do
|
57
50
|
Faye::Transport.stub(:get)
|
58
51
|
client = Faye::Client.new("http://localhost/")
|
@@ -63,6 +56,14 @@ describe Faye::Client do
|
|
63
56
|
describe :handshake do
|
64
57
|
before { create_client }
|
65
58
|
|
59
|
+
it "creates a transport the server must support" do
|
60
|
+
Faye::Transport.should_receive(:get).with(instance_of(Faye::Client),
|
61
|
+
["long-polling", "callback-polling", "in-process"],
|
62
|
+
[]).
|
63
|
+
and_yield(transport)
|
64
|
+
@client.handshake
|
65
|
+
end
|
66
|
+
|
66
67
|
it "sends a handshake message to the server" do
|
67
68
|
transport.should_receive(:send).with({
|
68
69
|
"channel" => "/meta/handshake",
|
@@ -89,7 +90,7 @@ describe Faye::Client do
|
|
89
90
|
end
|
90
91
|
@client.add_extension(extension.new)
|
91
92
|
end
|
92
|
-
|
93
|
+
|
93
94
|
it "passes the handshake message through the extension" do
|
94
95
|
transport.should_receive(:send).with({
|
95
96
|
"channel" => "/meta/handshake",
|
@@ -120,23 +121,27 @@ describe Faye::Client do
|
|
120
121
|
@client.handshake
|
121
122
|
@client.state.should == :CONNECTED
|
122
123
|
end
|
123
|
-
|
124
|
+
|
124
125
|
it "registers any pre-existing subscriptions" do
|
125
126
|
@client.should_receive(:subscribe).with([], true)
|
126
127
|
@client.handshake
|
127
128
|
end
|
128
|
-
|
129
|
+
|
129
130
|
it "selects a new transport based on what the server supports" do
|
130
|
-
Faye::Transport.should_receive(:get).with(instance_of(Faye::Client),
|
131
|
+
Faye::Transport.should_receive(:get).with(instance_of(Faye::Client),
|
132
|
+
["long-polling", "websocket"],
|
133
|
+
[]).
|
131
134
|
and_return(transport)
|
132
135
|
@client.handshake
|
133
136
|
end
|
134
|
-
|
137
|
+
|
135
138
|
describe "with websocket disabled" do
|
136
139
|
before { @client.disable("websocket") }
|
137
|
-
|
140
|
+
|
138
141
|
it "selects a new transport, excluding websocket" do
|
139
|
-
Faye::Transport.should_receive(:get).with(instance_of(Faye::Client),
|
142
|
+
Faye::Transport.should_receive(:get).with(instance_of(Faye::Client),
|
143
|
+
["long-polling", "websocket"],
|
144
|
+
["websocket"]).
|
140
145
|
and_return(transport)
|
141
146
|
@client.handshake
|
142
147
|
end
|
@@ -162,23 +167,23 @@ describe Faye::Client do
|
|
162
167
|
@client.state.should == :UNCONNECTED
|
163
168
|
end
|
164
169
|
end
|
165
|
-
|
170
|
+
|
166
171
|
describe "with existing subscriptions after a server restart" do
|
167
172
|
before do
|
168
173
|
create_connected_client
|
169
|
-
|
174
|
+
|
170
175
|
@message = nil
|
171
176
|
subscribe @client, "/messages/foo", lambda { |m| @message = m }
|
172
|
-
|
177
|
+
|
173
178
|
@client.receive_message "advice" => {"reconnect" => "handshake"}
|
174
|
-
|
179
|
+
|
175
180
|
stub_response "channel" => "/meta/handshake",
|
176
181
|
"successful" => true,
|
177
182
|
"version" => "1.0",
|
178
183
|
"supportedConnectionTypes" => ["websocket"],
|
179
184
|
"clientId" => "reconnectid"
|
180
185
|
end
|
181
|
-
|
186
|
+
|
182
187
|
it "resends the subscriptions to the server" do
|
183
188
|
transport.should_receive(:send).with(hash_including("channel" => "/meta/handshake"), 60)
|
184
189
|
transport.should_receive(:send).with({
|
@@ -189,17 +194,17 @@ describe Faye::Client do
|
|
189
194
|
}, 60)
|
190
195
|
@client.handshake
|
191
196
|
end
|
192
|
-
|
197
|
+
|
193
198
|
it "retains the listeners for the subscriptions" do
|
194
199
|
@client.handshake
|
195
200
|
@client.receive_message("channel" => "/messages/foo", "data" => "ok")
|
196
201
|
@message.should == "ok"
|
197
202
|
end
|
198
203
|
end
|
199
|
-
|
204
|
+
|
200
205
|
describe "with a connected client" do
|
201
206
|
before { create_connected_client }
|
202
|
-
|
207
|
+
|
203
208
|
it "does not send a handshake message to the server" do
|
204
209
|
transport.should_not_receive(:send).with({
|
205
210
|
"channel" => "/meta/handshake",
|
@@ -211,7 +216,7 @@ describe Faye::Client do
|
|
211
216
|
end
|
212
217
|
end
|
213
218
|
end
|
214
|
-
|
219
|
+
|
215
220
|
describe :connect do
|
216
221
|
describe "with an unconnected client" do
|
217
222
|
before do
|
@@ -220,10 +225,10 @@ describe Faye::Client do
|
|
220
225
|
"version" => "1.0",
|
221
226
|
"supportedConnectionTypes" => ["websocket"],
|
222
227
|
"clientId" => "handshakeid"
|
223
|
-
|
228
|
+
|
224
229
|
create_client
|
225
230
|
end
|
226
|
-
|
231
|
+
|
227
232
|
it "handshakes before connecting" do
|
228
233
|
transport.should_receive(:send).with({
|
229
234
|
"channel" => "/meta/connect",
|
@@ -234,10 +239,10 @@ describe Faye::Client do
|
|
234
239
|
@client.connect
|
235
240
|
end
|
236
241
|
end
|
237
|
-
|
242
|
+
|
238
243
|
describe "with a connected client" do
|
239
244
|
before { create_connected_client }
|
240
|
-
|
245
|
+
|
241
246
|
it "sends a connect message to the server" do
|
242
247
|
transport.should_receive(:send).with({
|
243
248
|
"channel" => "/meta/connect",
|
@@ -247,7 +252,7 @@ describe Faye::Client do
|
|
247
252
|
}, 60)
|
248
253
|
@client.connect
|
249
254
|
end
|
250
|
-
|
255
|
+
|
251
256
|
it "only opens one connect request at a time" do
|
252
257
|
transport.should_receive(:send).with({
|
253
258
|
"channel" => "/meta/connect",
|
@@ -257,16 +262,16 @@ describe Faye::Client do
|
|
257
262
|
}, 60).
|
258
263
|
exactly(1).
|
259
264
|
and_return # override stub implementation
|
260
|
-
|
265
|
+
|
261
266
|
@client.connect
|
262
267
|
@client.connect
|
263
268
|
end
|
264
269
|
end
|
265
270
|
end
|
266
|
-
|
271
|
+
|
267
272
|
describe :disconnect do
|
268
273
|
before { create_connected_client }
|
269
|
-
|
274
|
+
|
270
275
|
it "sends a disconnect message to the server" do
|
271
276
|
transport.stub(:close)
|
272
277
|
transport.should_receive(:send).with({
|
@@ -276,27 +281,27 @@ describe Faye::Client do
|
|
276
281
|
}, 60)
|
277
282
|
@client.disconnect
|
278
283
|
end
|
279
|
-
|
284
|
+
|
280
285
|
it "puts the client in the DISCONNECTED state" do
|
281
286
|
transport.stub(:close)
|
282
287
|
@client.disconnect
|
283
288
|
@client.state.should == :DISCONNECTED
|
284
289
|
end
|
285
|
-
|
290
|
+
|
286
291
|
describe "on successful response" do
|
287
292
|
before do
|
288
293
|
stub_response "channel" => "/meta/disconnect",
|
289
294
|
"successful" => true,
|
290
295
|
"clientId" => "fakeid"
|
291
296
|
end
|
292
|
-
|
297
|
+
|
293
298
|
it "closes the transport" do
|
294
299
|
transport.should_receive(:close)
|
295
300
|
@client.disconnect
|
296
301
|
end
|
297
302
|
end
|
298
303
|
end
|
299
|
-
|
304
|
+
|
300
305
|
describe :subscribe do
|
301
306
|
before do
|
302
307
|
create_connected_client
|
@@ -307,13 +312,13 @@ describe Faye::Client do
|
|
307
312
|
"id" => instance_of(String)
|
308
313
|
}
|
309
314
|
end
|
310
|
-
|
315
|
+
|
311
316
|
describe "with no prior subscriptions" do
|
312
317
|
it "sends a subscribe message to the server" do
|
313
318
|
transport.should_receive(:send).with(@subscribe_message, 60)
|
314
319
|
@client.subscribe("/foo/*")
|
315
320
|
end
|
316
|
-
|
321
|
+
|
317
322
|
# The Bayeux spec says the server should accept a list of subscriptions
|
318
323
|
# in one message but the cometD server doesn't actually support this
|
319
324
|
describe "with an array of subscriptions" do
|
@@ -332,7 +337,7 @@ describe Faye::Client do
|
|
332
337
|
}, 60)
|
333
338
|
@client.subscribe(["/foo", "/bar"])
|
334
339
|
end
|
335
|
-
|
340
|
+
|
336
341
|
it "returns an array of subscriptions" do
|
337
342
|
transport.stub(:send)
|
338
343
|
subs = @client.subscribe(["/foo", "/bar"])
|
@@ -340,7 +345,7 @@ describe Faye::Client do
|
|
340
345
|
subs.should be_all { |s| Faye::Subscription === s }
|
341
346
|
end
|
342
347
|
end
|
343
|
-
|
348
|
+
|
344
349
|
describe "on successful response" do
|
345
350
|
before do
|
346
351
|
stub_response "channel" => "/meta/subscribe",
|
@@ -348,27 +353,27 @@ describe Faye::Client do
|
|
348
353
|
"clientId" => "fakeid",
|
349
354
|
"subscription" => "/foo/*"
|
350
355
|
end
|
351
|
-
|
356
|
+
|
352
357
|
it "sets up a listener for the subscribed channel" do
|
353
358
|
@message = nil
|
354
359
|
@client.subscribe("/foo/*") { |m| @message = m }
|
355
360
|
@client.receive_message("channel" => "/foo/bar", "data" => "hi")
|
356
361
|
@message.should == "hi"
|
357
362
|
end
|
358
|
-
|
363
|
+
|
359
364
|
it "does not call the listener for non-matching channels" do
|
360
365
|
@message = nil
|
361
366
|
@client.subscribe("/foo/*") { |m| @message = m }
|
362
367
|
@client.receive_message("channel" => "/bar", "data" => "hi")
|
363
368
|
@message.should be_nil
|
364
369
|
end
|
365
|
-
|
370
|
+
|
366
371
|
it "activates the subscription" do
|
367
372
|
active = false
|
368
373
|
@client.subscribe("/foo/*").callback { active = true }
|
369
374
|
active.should be_true
|
370
375
|
end
|
371
|
-
|
376
|
+
|
372
377
|
describe "with an incoming extension installed" do
|
373
378
|
before do
|
374
379
|
extension = Class.new do
|
@@ -381,13 +386,13 @@ describe Faye::Client do
|
|
381
386
|
@message = nil
|
382
387
|
@client.subscribe("/foo/*") { |m| @message = m }
|
383
388
|
end
|
384
|
-
|
389
|
+
|
385
390
|
it "passes delivered messages through the extension" do
|
386
391
|
@client.receive_message("channel" => "/foo/bar", "data" => {"hello" => "there"})
|
387
392
|
@message.should == {"hello" => "there", "changed" => true}
|
388
393
|
end
|
389
394
|
end
|
390
|
-
|
395
|
+
|
391
396
|
describe "with an outgoing extension installed" do
|
392
397
|
before do
|
393
398
|
extension = Class.new do
|
@@ -400,13 +405,13 @@ describe Faye::Client do
|
|
400
405
|
@message = nil
|
401
406
|
@client.subscribe("/foo/*") { |m| @message = m }
|
402
407
|
end
|
403
|
-
|
408
|
+
|
404
409
|
it "leaves messages unchanged" do
|
405
410
|
@client.receive_message("channel" => "/foo/bar", "data" => {"hello" => "there"})
|
406
411
|
@message.should == {"hello" => "there"}
|
407
412
|
end
|
408
413
|
end
|
409
|
-
|
414
|
+
|
410
415
|
describe "with an incoming extension that invalidates the response" do
|
411
416
|
before do
|
412
417
|
extension = Class.new do
|
@@ -417,14 +422,14 @@ describe Faye::Client do
|
|
417
422
|
end
|
418
423
|
@client.add_extension(extension.new)
|
419
424
|
end
|
420
|
-
|
425
|
+
|
421
426
|
it "does not set up a listener for the subscribed channel" do
|
422
427
|
@message = nil
|
423
428
|
@client.subscribe("/foo/*") { |m| @message = m }
|
424
429
|
@client.receive_message("channel" => "/foo/bar", "data" => "hi")
|
425
430
|
@message.should be_nil
|
426
431
|
end
|
427
|
-
|
432
|
+
|
428
433
|
it "does not activate the subscription" do
|
429
434
|
active = false
|
430
435
|
@client.subscribe("/foo/*").callback { active = true }
|
@@ -432,7 +437,7 @@ describe Faye::Client do
|
|
432
437
|
end
|
433
438
|
end
|
434
439
|
end
|
435
|
-
|
440
|
+
|
436
441
|
describe "on unsuccessful response" do
|
437
442
|
before do
|
438
443
|
stub_response "channel" => "/meta/subscribe",
|
@@ -441,14 +446,14 @@ describe Faye::Client do
|
|
441
446
|
"clientId" => "fakeid",
|
442
447
|
"subscription" => "/meta/foo"
|
443
448
|
end
|
444
|
-
|
449
|
+
|
445
450
|
it "does not set up a listener for the subscribed channel" do
|
446
451
|
@message = nil
|
447
452
|
@client.subscribe("/meta/foo") { |m| @message = m }
|
448
453
|
@client.receive_message("channel" => "/meta/foo", "data" => "hi")
|
449
454
|
@message.should be_nil
|
450
455
|
end
|
451
|
-
|
456
|
+
|
452
457
|
it "does not activate the subscription" do
|
453
458
|
active = false
|
454
459
|
@client.subscribe("/meta/foo").callback { active = true }
|
@@ -464,23 +469,23 @@ describe Faye::Client do
|
|
464
469
|
end
|
465
470
|
end
|
466
471
|
end
|
467
|
-
|
472
|
+
|
468
473
|
describe "with an existing subscription" do
|
469
474
|
before do
|
470
475
|
subscribe @client, "/foo/*"
|
471
476
|
end
|
472
|
-
|
477
|
+
|
473
478
|
it "does not send another subscribe message to the server" do
|
474
479
|
transport.should_not_receive(:send).with(@subscribe_message, 60)
|
475
480
|
@client.subscribe("/foo/*")
|
476
481
|
end
|
477
|
-
|
482
|
+
|
478
483
|
it "sets up another listener on the channel" do
|
479
484
|
@client.subscribe("/foo/*") { @subs_called += 1 }
|
480
485
|
@client.receive_message("channel" => "/foo/bar", "data" => "hi")
|
481
486
|
@subs_called.should == 2
|
482
487
|
end
|
483
|
-
|
488
|
+
|
484
489
|
it "activates the subscription" do
|
485
490
|
active = false
|
486
491
|
@client.subscribe("/foo/*").callback { active = true }
|
@@ -488,7 +493,7 @@ describe Faye::Client do
|
|
488
493
|
end
|
489
494
|
end
|
490
495
|
end
|
491
|
-
|
496
|
+
|
492
497
|
describe :unsubscribe do
|
493
498
|
before do
|
494
499
|
create_connected_client
|
@@ -499,26 +504,26 @@ describe Faye::Client do
|
|
499
504
|
"id" => instance_of(String)
|
500
505
|
}
|
501
506
|
end
|
502
|
-
|
507
|
+
|
503
508
|
describe "with no subscriptions" do
|
504
509
|
it "does not send an unsubscribe message to the server" do
|
505
510
|
transport.should_not_receive(:send).with(@unsubscribe_message, 60)
|
506
511
|
@client.unsubscribe("/foo/*")
|
507
512
|
end
|
508
513
|
end
|
509
|
-
|
514
|
+
|
510
515
|
describe "with a single subscription" do
|
511
516
|
before do
|
512
517
|
@message = nil
|
513
518
|
@listener = lambda { |m| @message = m }
|
514
519
|
subscribe @client, "/foo/*", @listener
|
515
520
|
end
|
516
|
-
|
521
|
+
|
517
522
|
it "sends an unsubscribe message to the server" do
|
518
523
|
transport.should_receive(:send).with(@unsubscribe_message, 60)
|
519
524
|
@client.unsubscribe("/foo/*")
|
520
525
|
end
|
521
|
-
|
526
|
+
|
522
527
|
it "removes the listener from the channel" do
|
523
528
|
@client.receive_message("channel" => "/foo/bar", "data" => "first")
|
524
529
|
@client.unsubscribe("/foo/*", &@listener)
|
@@ -526,7 +531,7 @@ describe Faye::Client do
|
|
526
531
|
@message.should == "first"
|
527
532
|
end
|
528
533
|
end
|
529
|
-
|
534
|
+
|
530
535
|
describe "with multiple subscriptions to the same channel" do
|
531
536
|
before do
|
532
537
|
@messages = []
|
@@ -535,37 +540,37 @@ describe Faye::Client do
|
|
535
540
|
subscribe @client, "/foo/*", @hey
|
536
541
|
subscribe @client, "/foo/*", @bye
|
537
542
|
end
|
538
|
-
|
543
|
+
|
539
544
|
it "removes one of the listeners from the channel" do
|
540
545
|
@client.receive_message("channel" => "/foo/bar", "data" => {"text" => "you"})
|
541
546
|
@client.unsubscribe("/foo/*", &@hey)
|
542
547
|
@client.receive_message("channel" => "/foo/bar", "data" => {"text" => "you"})
|
543
548
|
@messages.should == ["hey you", "bye you", "bye you"]
|
544
549
|
end
|
545
|
-
|
550
|
+
|
546
551
|
it "does not send an unsubscribe message if one listener is removed" do
|
547
552
|
transport.should_not_receive(:send).with(@unsubscribe_message, 60)
|
548
553
|
@client.unsubscribe("/foo/*", &@bye)
|
549
554
|
end
|
550
|
-
|
555
|
+
|
551
556
|
it "sends an unsubscribe message if each listener is removed" do
|
552
557
|
transport.should_receive(:send).with(@unsubscribe_message, 60)
|
553
558
|
@client.unsubscribe("/foo/*", &@bye)
|
554
559
|
@client.unsubscribe("/foo/*", &@hey)
|
555
560
|
end
|
556
|
-
|
561
|
+
|
557
562
|
it "sends an unsubscribe message if all listeners are removed" do
|
558
563
|
transport.should_receive(:send).with(@unsubscribe_message, 60)
|
559
564
|
@client.unsubscribe("/foo/*")
|
560
565
|
end
|
561
566
|
end
|
562
|
-
|
567
|
+
|
563
568
|
describe "with multiple subscriptions to different channels" do
|
564
569
|
before do
|
565
570
|
subscribe @client, "/foo"
|
566
571
|
subscribe @client, "/bar"
|
567
572
|
end
|
568
|
-
|
573
|
+
|
569
574
|
it "sends multiple unsubscribe messages if given an array" do
|
570
575
|
transport.should_receive(:send).with({
|
571
576
|
"channel" => "/meta/unsubscribe",
|
@@ -583,10 +588,10 @@ describe Faye::Client do
|
|
583
588
|
end
|
584
589
|
end
|
585
590
|
end
|
586
|
-
|
591
|
+
|
587
592
|
describe :publish do
|
588
593
|
before { create_connected_client }
|
589
|
-
|
594
|
+
|
590
595
|
it "sends the message to the server with an ID" do
|
591
596
|
transport.should_receive(:send).with({
|
592
597
|
"channel" => "/messages/foo",
|
@@ -596,12 +601,12 @@ describe Faye::Client do
|
|
596
601
|
}, 60)
|
597
602
|
@client.publish("/messages/foo", "hello" => "world")
|
598
603
|
end
|
599
|
-
|
604
|
+
|
600
605
|
it "throws an error when publishing to an invalid channel" do
|
601
606
|
transport.should_not_receive(:send).with(hash_including("channel" => "/messages/*"), 60)
|
602
607
|
lambda { @client.publish("/messages/*", "hello" => "world") }.should raise_error
|
603
608
|
end
|
604
|
-
|
609
|
+
|
605
610
|
describe "on publish failure" do
|
606
611
|
before do
|
607
612
|
stub_response "channel" => "/messages/foo",
|
@@ -624,7 +629,7 @@ describe Faye::Client do
|
|
624
629
|
error.message.should == "Failed to publish"
|
625
630
|
end
|
626
631
|
end
|
627
|
-
|
632
|
+
|
628
633
|
describe "on receipt of the published message" do
|
629
634
|
before do
|
630
635
|
stub_response "channel" => "/messages/foo",
|
@@ -651,7 +656,7 @@ describe Faye::Client do
|
|
651
656
|
end
|
652
657
|
@client.add_extension(extension.new)
|
653
658
|
end
|
654
|
-
|
659
|
+
|
655
660
|
it "passes messages through the extension" do
|
656
661
|
transport.should_receive(:send).with({
|
657
662
|
"channel" => "/messages/foo",
|
@@ -663,7 +668,7 @@ describe Faye::Client do
|
|
663
668
|
@client.publish("/messages/foo", "hello" => "world")
|
664
669
|
end
|
665
670
|
end
|
666
|
-
|
671
|
+
|
667
672
|
describe "with an incoming extension installed" do
|
668
673
|
before do
|
669
674
|
extension = Class.new do
|
@@ -674,7 +679,7 @@ describe Faye::Client do
|
|
674
679
|
end
|
675
680
|
@client.add_extension(extension.new)
|
676
681
|
end
|
677
|
-
|
682
|
+
|
678
683
|
it "leaves the message unchanged" do
|
679
684
|
transport.should_receive(:send).with({
|
680
685
|
"channel" => "/messages/foo",
|
@@ -686,44 +691,47 @@ describe Faye::Client do
|
|
686
691
|
end
|
687
692
|
end
|
688
693
|
end
|
689
|
-
|
694
|
+
|
690
695
|
describe "network notifications" do
|
691
|
-
before {
|
692
|
-
|
696
|
+
before {
|
697
|
+
create_client
|
698
|
+
@client.handshake
|
699
|
+
}
|
700
|
+
|
693
701
|
describe "in the default state" do
|
694
702
|
it "broadcasts a down notification" do
|
695
703
|
@client.should_receive(:trigger).with("transport:down")
|
696
704
|
transport.trigger(:down)
|
697
705
|
end
|
698
|
-
|
706
|
+
|
699
707
|
it "broadcasts an up notification" do
|
700
708
|
@client.should_receive(:trigger).with("transport:up")
|
701
709
|
transport.trigger(:up)
|
702
710
|
end
|
703
711
|
end
|
704
|
-
|
712
|
+
|
705
713
|
describe "when the transport is up" do
|
706
714
|
before { transport.trigger(:up) }
|
707
|
-
|
715
|
+
|
708
716
|
it "broadcasts a down notification" do
|
709
717
|
@client.should_receive(:trigger).with("transport:down")
|
710
718
|
transport.trigger(:down)
|
711
719
|
end
|
712
|
-
|
720
|
+
|
713
721
|
it "does not broadcast an up notification" do
|
714
722
|
@client.should_not_receive(:trigger)
|
715
723
|
transport.trigger(:up)
|
716
724
|
end
|
717
725
|
end
|
718
|
-
|
726
|
+
|
719
727
|
describe "when the transport is down" do
|
720
728
|
before { transport.trigger(:down) }
|
721
|
-
|
729
|
+
|
722
730
|
it "does not broadcast a down notification" do
|
723
731
|
@client.should_not_receive(:trigger)
|
724
732
|
transport.trigger(:down)
|
725
733
|
end
|
726
|
-
|
734
|
+
|
727
735
|
it "broadcasts an up notification" do
|
728
736
|
@client.should_receive(:trigger).with("transport:up")
|
729
737
|
transport.trigger(:up)
|