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.

Files changed (67) hide show
  1. data/History.txt +16 -10
  2. data/README.rdoc +1 -1
  3. data/lib/faye-browser-min.js +1 -1
  4. data/lib/faye-browser-min.js.map +2 -2
  5. data/lib/faye-browser.js +302 -287
  6. data/lib/faye.rb +21 -21
  7. data/lib/faye/adapters/rack_adapter.rb +50 -48
  8. data/lib/faye/adapters/static_server.rb +22 -22
  9. data/lib/faye/engines/connection.rb +13 -13
  10. data/lib/faye/engines/memory.rb +21 -21
  11. data/lib/faye/engines/proxy.rb +23 -23
  12. data/lib/faye/error.rb +6 -6
  13. data/lib/faye/mixins/logging.rb +12 -12
  14. data/lib/faye/mixins/publisher.rb +6 -6
  15. data/lib/faye/mixins/timeouts.rb +1 -1
  16. data/lib/faye/protocol/channel.rb +24 -24
  17. data/lib/faye/protocol/client.rb +71 -73
  18. data/lib/faye/protocol/extensible.rb +7 -7
  19. data/lib/faye/protocol/grammar.rb +13 -13
  20. data/lib/faye/protocol/server.rb +57 -57
  21. data/lib/faye/protocol/socket.rb +4 -4
  22. data/lib/faye/protocol/subscription.rb +4 -4
  23. data/lib/faye/transport/http.rb +13 -13
  24. data/lib/faye/transport/local.rb +5 -5
  25. data/lib/faye/transport/transport.rb +25 -25
  26. data/lib/faye/transport/web_socket.rb +34 -30
  27. data/lib/faye/util/namespace.rb +4 -4
  28. data/spec/browser.html +5 -5
  29. data/spec/javascript/channel_spec.js +3 -3
  30. data/spec/javascript/client_spec.js +104 -98
  31. data/spec/javascript/engine/memory_spec.js +1 -1
  32. data/spec/javascript/engine_spec.js +70 -70
  33. data/spec/javascript/faye_spec.js +6 -6
  34. data/spec/javascript/grammar_spec.js +12 -12
  35. data/spec/javascript/node_adapter_spec.js +46 -46
  36. data/spec/javascript/publisher_spec.js +4 -4
  37. data/spec/javascript/server/connect_spec.js +21 -21
  38. data/spec/javascript/server/disconnect_spec.js +15 -15
  39. data/spec/javascript/server/extensions_spec.js +6 -6
  40. data/spec/javascript/server/handshake_spec.js +18 -18
  41. data/spec/javascript/server/integration_spec.js +23 -23
  42. data/spec/javascript/server/publish_spec.js +9 -9
  43. data/spec/javascript/server/subscribe_spec.js +30 -30
  44. data/spec/javascript/server/unsubscribe_spec.js +30 -30
  45. data/spec/javascript/server_spec.js +15 -15
  46. data/spec/javascript/transport_spec.js +32 -27
  47. data/spec/node.js +2 -2
  48. data/spec/ruby/channel_spec.rb +2 -2
  49. data/spec/ruby/client_spec.rb +100 -92
  50. data/spec/ruby/engine_examples.rb +51 -51
  51. data/spec/ruby/faye_spec.rb +5 -5
  52. data/spec/ruby/grammar_spec.rb +12 -12
  53. data/spec/ruby/publisher_spec.rb +4 -4
  54. data/spec/ruby/rack_adapter_spec.rb +34 -34
  55. data/spec/ruby/server/connect_spec.rb +22 -22
  56. data/spec/ruby/server/disconnect_spec.rb +16 -16
  57. data/spec/ruby/server/extensions_spec.rb +8 -8
  58. data/spec/ruby/server/handshake_spec.rb +20 -20
  59. data/spec/ruby/server/integration_spec.rb +22 -24
  60. data/spec/ruby/server/publish_spec.rb +9 -9
  61. data/spec/ruby/server/subscribe_spec.rb +31 -31
  62. data/spec/ruby/server/unsubscribe_spec.rb +31 -31
  63. data/spec/ruby/server_spec.rb +17 -17
  64. data/spec/ruby/transport_spec.rb +23 -23
  65. data/spec/testswarm +23 -10
  66. data/spec/thin_proxy.rb +5 -5
  67. 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 = {endpoint: "http://example.com/", endpoints: {}, transports: {}}
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)
@@ -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',
@@ -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
@@ -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), ["long-polling", "websocket"]).
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), ["long-polling"]).
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 { create_client }
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)