faye 0.6.8 → 0.7.0
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 +10 -3
- data/README.rdoc +1 -2
- data/lib/faye-browser-min.js +1 -1
- data/lib/faye.rb +89 -32
- data/lib/faye/adapters/rack_adapter.rb +20 -26
- data/lib/faye/engines/base.rb +5 -0
- data/lib/faye/engines/memory.rb +9 -3
- data/lib/faye/engines/redis.rb +26 -11
- data/lib/faye/mixins/publisher.rb +4 -8
- data/lib/faye/protocol/channel.rb +8 -8
- data/lib/faye/protocol/client.rb +45 -4
- data/lib/faye/protocol/publication.rb +5 -0
- data/lib/faye/protocol/server.rb +10 -19
- data/lib/faye/thin_extensions.rb +1 -1
- data/lib/faye/transport/http.rb +17 -8
- data/lib/faye/transport/local.rb +6 -3
- data/lib/faye/transport/transport.rb +23 -9
- data/lib/faye/transport/web_socket.rb +102 -0
- data/lib/faye/util/web_socket.rb +34 -80
- data/lib/faye/util/web_socket/api.rb +103 -0
- data/lib/faye/util/web_socket/client.rb +82 -0
- data/lib/faye/util/web_socket/draft75_parser.rb +3 -5
- data/lib/faye/util/web_socket/draft76_parser.rb +5 -7
- data/lib/faye/util/web_socket/protocol8_parser.rb +111 -46
- data/spec/javascript/client_spec.js +99 -7
- data/spec/javascript/engine_spec.js +116 -3
- data/spec/javascript/node_adapter_spec.js +2 -4
- data/spec/javascript/server/handshake_spec.js +0 -12
- data/spec/javascript/server/integration_spec.js +74 -29
- data/spec/javascript/server_spec.js +0 -11
- data/spec/javascript/web_socket/client_spec.js +121 -0
- data/spec/javascript/web_socket/protocol8parser_spec.js +26 -3
- data/spec/node.js +2 -0
- data/spec/redis.conf +10 -280
- data/spec/ruby/client_spec.rb +101 -8
- data/spec/ruby/engine_spec.rb +106 -0
- data/spec/ruby/server/handshake_spec.rb +0 -12
- data/spec/ruby/server/integration_spec.rb +56 -18
- data/spec/ruby/server_spec.rb +1 -12
- data/spec/ruby/transport_spec.rb +14 -8
- data/spec/ruby/web_socket/client_spec.rb +126 -0
- data/spec/ruby/web_socket/protocol8_parser_spec.rb +28 -3
- metadata +96 -150
@@ -1,6 +1,7 @@
|
|
1
1
|
JS.ENV.ClientSpec = JS.Test.describe("Client", function() { with(this) {
|
2
2
|
before(function() { with(this) {
|
3
3
|
this.transport = {connectionType: "fake", send: function() {}}
|
4
|
+
Faye.extend(transport, Faye.Publisher)
|
4
5
|
stub(Faye.Transport, "get").yields([transport])
|
5
6
|
}})
|
6
7
|
|
@@ -103,7 +104,7 @@ JS.ENV.ClientSpec = JS.Test.describe("Client", function() { with(this) {
|
|
103
104
|
stubResponse({channel: "/meta/handshake",
|
104
105
|
successful: true,
|
105
106
|
version: "1.0",
|
106
|
-
supportedConnectionTypes: ["websocket"],
|
107
|
+
supportedConnectionTypes: ["long-polling", "websocket"],
|
107
108
|
clientId: "fakeid" })
|
108
109
|
}})
|
109
110
|
|
@@ -116,16 +117,26 @@ JS.ENV.ClientSpec = JS.Test.describe("Client", function() { with(this) {
|
|
116
117
|
client.handshake()
|
117
118
|
assertEqual( "CONNECTED", client.getState() )
|
118
119
|
}})
|
119
|
-
|
120
|
+
|
121
|
+
it("registers any pre-existing subscriptions", function() { with(this) {
|
122
|
+
expect(client, "subscribe").given([], true)
|
123
|
+
client.handshake()
|
124
|
+
}})
|
125
|
+
|
120
126
|
it("selects a new transport based on what the server supports", function() { with(this) {
|
121
|
-
expect(Faye.Transport, "get").given(instanceOf(Faye.Client), ["websocket"])
|
127
|
+
expect(Faye.Transport, "get").given(instanceOf(Faye.Client), ["long-polling", "websocket"])
|
122
128
|
.yielding([transport])
|
123
129
|
client.handshake()
|
124
130
|
}})
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
131
|
+
|
132
|
+
describe("with websocket disabled", function() { with(this) {
|
133
|
+
before(function() { this.client.disable('websocket') })
|
134
|
+
|
135
|
+
it("selects a new transport, excluding websocket", function() { with(this) {
|
136
|
+
expect(Faye.Transport, "get").given(instanceOf(Faye.Client), ["long-polling"])
|
137
|
+
.yielding([transport])
|
138
|
+
client.handshake()
|
139
|
+
}})
|
129
140
|
}})
|
130
141
|
}})
|
131
142
|
|
@@ -264,9 +275,23 @@ JS.ENV.ClientSpec = JS.Test.describe("Client", function() { with(this) {
|
|
264
275
|
}})
|
265
276
|
|
266
277
|
it("puts the client in the DISCONNECTED state", function() { with(this) {
|
278
|
+
stub(transport, "close")
|
267
279
|
client.disconnect()
|
268
280
|
assertEqual( "DISCONNECTED", client.getState() )
|
269
281
|
}})
|
282
|
+
|
283
|
+
describe("on successful response", function() { with(this) {
|
284
|
+
before(function() { with(this) {
|
285
|
+
stubResponse({channel: "/meta/disconnect",
|
286
|
+
successful: true,
|
287
|
+
clientId: "fakeid" })
|
288
|
+
}})
|
289
|
+
|
290
|
+
it("closes the transport", function() { with(this) {
|
291
|
+
expect(transport, "close")
|
292
|
+
client.disconnect()
|
293
|
+
}})
|
294
|
+
}})
|
270
295
|
}})
|
271
296
|
|
272
297
|
describe("subscribe", function() { with(this) {
|
@@ -563,6 +588,29 @@ JS.ENV.ClientSpec = JS.Test.describe("Client", function() { with(this) {
|
|
563
588
|
assertThrows(Error, function() { client.publish("/messages/*", {hello: "world"}) })
|
564
589
|
}})
|
565
590
|
|
591
|
+
describe("on publish failure", function() { with(this) {
|
592
|
+
before(function() { with(this) {
|
593
|
+
stubResponse({channel: "/messages/foo",
|
594
|
+
error: "407:/messages/foo:Failed to publish",
|
595
|
+
successful: false,
|
596
|
+
clientId: "fakeid" })
|
597
|
+
}})
|
598
|
+
|
599
|
+
it("should not be published", function() { with(this) {
|
600
|
+
var published = false
|
601
|
+
client.publish("/messages/foo", {text: "hi"}).callback(function() { published = true })
|
602
|
+
assert( !published )
|
603
|
+
}})
|
604
|
+
|
605
|
+
it("reports the error through an errback", function() { with(this) {
|
606
|
+
var error = null
|
607
|
+
client.publish("/messages/foo", {text: "hi"}).errback(function(e) { error = e })
|
608
|
+
assertEqual( 407, error.code )
|
609
|
+
assertEqual( ["/messages/foo"], error.params )
|
610
|
+
assertEqual( "Failed to publish", error.message )
|
611
|
+
}})
|
612
|
+
}})
|
613
|
+
|
566
614
|
describe("with an outgoing extension installed", function() { with(this) {
|
567
615
|
before(function() { with(this) {
|
568
616
|
var extension = {
|
@@ -608,4 +656,48 @@ JS.ENV.ClientSpec = JS.Test.describe("Client", function() { with(this) {
|
|
608
656
|
}})
|
609
657
|
}})
|
610
658
|
}})
|
659
|
+
|
660
|
+
describe("network notifications", function() { with(this) {
|
661
|
+
before(function() { this.createClient() })
|
662
|
+
|
663
|
+
describe("in the default state", function() { with(this) {
|
664
|
+
it("broadcasts a down notification", function() { with(this) {
|
665
|
+
expect(client, "trigger").given("transport:down")
|
666
|
+
transport.trigger("down")
|
667
|
+
}})
|
668
|
+
|
669
|
+
it("broadcasts an up notification", function() { with(this) {
|
670
|
+
expect(client, "trigger").given("transport:up")
|
671
|
+
transport.trigger("up")
|
672
|
+
}})
|
673
|
+
}})
|
674
|
+
|
675
|
+
describe("when the transport is up", function() { with(this) {
|
676
|
+
before(function() { this.transport.trigger("up") })
|
677
|
+
|
678
|
+
it("broadcasts a down notification", function() { with(this) {
|
679
|
+
expect(client, "trigger").given("transport:down")
|
680
|
+
transport.trigger("down")
|
681
|
+
}})
|
682
|
+
|
683
|
+
it("does not broadcast an up notification", function() { with(this) {
|
684
|
+
expect(client, "trigger").exactly(0)
|
685
|
+
transport.trigger("up")
|
686
|
+
}})
|
687
|
+
}})
|
688
|
+
|
689
|
+
describe("when the transport is down", function() { with(this) {
|
690
|
+
before(function() { this.transport.trigger("down") })
|
691
|
+
|
692
|
+
it("does not broadcast a down notification", function() { with(this) {
|
693
|
+
expect(client, "trigger").exactly(0)
|
694
|
+
transport.trigger("down")
|
695
|
+
}})
|
696
|
+
|
697
|
+
it("broadcasts an up notification", function() { with(this) {
|
698
|
+
expect(client, "trigger").given("transport:up")
|
699
|
+
transport.trigger("up")
|
700
|
+
}})
|
701
|
+
}})
|
702
|
+
}})
|
611
703
|
}})
|
@@ -62,6 +62,12 @@ JS.ENV.EngineSteps = JS.Test.asyncSteps({
|
|
62
62
|
setTimeout(resume, 20)
|
63
63
|
},
|
64
64
|
|
65
|
+
publish_by: function(name, message, resume) {
|
66
|
+
message = Faye.extend({clientId: this._clients[name], id: Faye.random()}, message)
|
67
|
+
this.engine.publish(message)
|
68
|
+
setTimeout(resume, 10)
|
69
|
+
},
|
70
|
+
|
65
71
|
ping: function(name, resume) {
|
66
72
|
this.engine.ping(this._clients[name])
|
67
73
|
resume()
|
@@ -71,6 +77,24 @@ JS.ENV.EngineSteps = JS.Test.asyncSteps({
|
|
71
77
|
setTimeout(resume, time)
|
72
78
|
},
|
73
79
|
|
80
|
+
expect_event: function(name, event, args, resume) {
|
81
|
+
var params = [this._clients[name]].concat(args),
|
82
|
+
handler = function() {}
|
83
|
+
|
84
|
+
this.engine.bind(event, handler)
|
85
|
+
this.expect(handler, "apply").given(undefined, params)
|
86
|
+
resume()
|
87
|
+
},
|
88
|
+
|
89
|
+
expect_no_event: function(name, event, args, resume) {
|
90
|
+
var params = [this._clients[name]].concat(args),
|
91
|
+
handler = function() {}
|
92
|
+
|
93
|
+
this.engine.bind(event, handler)
|
94
|
+
this.expect(handler, "apply").exactly(0)
|
95
|
+
resume()
|
96
|
+
},
|
97
|
+
|
74
98
|
expect_message: function(name, messages, resume) {
|
75
99
|
this.assertEqual(messages, this._inboxes[name])
|
76
100
|
resume()
|
@@ -81,6 +105,11 @@ JS.ENV.EngineSteps = JS.Test.asyncSteps({
|
|
81
105
|
resume()
|
82
106
|
},
|
83
107
|
|
108
|
+
check_different_messages: function(a, b, resume) {
|
109
|
+
this.assertNotSame(this._inboxes[a][0], this._inboxes[b][0])
|
110
|
+
resume()
|
111
|
+
},
|
112
|
+
|
84
113
|
clean_redis_db: function(resume) {
|
85
114
|
this.engine.disconnect()
|
86
115
|
var redis = require('redis').createClient(6379, 'localhost', {no_ready_check: true})
|
@@ -122,6 +151,11 @@ JS.ENV.EngineSpec = JS.Test.describe("Pub/sub engines", function() { with(this)
|
|
122
151
|
$R(1,7).forEach(function(i) { create_client("client" + i) })
|
123
152
|
check_num_clients(10)
|
124
153
|
}})
|
154
|
+
|
155
|
+
it("publishes an event", function() { with(this) {
|
156
|
+
expect(engine, "trigger").given("handshake", match(/^[a-z0-9]+$/))
|
157
|
+
create_client("dave")
|
158
|
+
}})
|
125
159
|
}})
|
126
160
|
|
127
161
|
describe("clientExists", function() { with(this) {
|
@@ -143,11 +177,11 @@ JS.ENV.EngineSpec = JS.Test.describe("Pub/sub engines", function() { with(this)
|
|
143
177
|
}})
|
144
178
|
|
145
179
|
it("prolongs the life of a client", function() { with(this) {
|
146
|
-
clock_tick(
|
180
|
+
clock_tick(450)
|
147
181
|
ping("alice")
|
148
|
-
clock_tick(
|
182
|
+
clock_tick(450)
|
149
183
|
check_client_exists("alice", true)
|
150
|
-
clock_tick(
|
184
|
+
clock_tick(450)
|
151
185
|
check_client_exists("alice", false)
|
152
186
|
}})
|
153
187
|
}})
|
@@ -157,6 +191,11 @@ JS.ENV.EngineSpec = JS.Test.describe("Pub/sub engines", function() { with(this)
|
|
157
191
|
destroy_client("alice")
|
158
192
|
check_client_exists("alice", false)
|
159
193
|
}})
|
194
|
+
|
195
|
+
it("publishes an event", function() { with(this) {
|
196
|
+
expect_event("alice", "disconnect", [])
|
197
|
+
destroy_client("alice")
|
198
|
+
}})
|
160
199
|
|
161
200
|
describe("when the client has subscriptions", function() { with(this) {
|
162
201
|
before(function() { with(this) {
|
@@ -170,6 +209,46 @@ JS.ENV.EngineSpec = JS.Test.describe("Pub/sub engines", function() { with(this)
|
|
170
209
|
publish(message)
|
171
210
|
expect_no_message("alice")
|
172
211
|
}})
|
212
|
+
|
213
|
+
it("publishes an event", function() { with(this) {
|
214
|
+
expect_event("alice", "disconnect", [])
|
215
|
+
destroy_client("alice")
|
216
|
+
}})
|
217
|
+
}})
|
218
|
+
}})
|
219
|
+
|
220
|
+
describe("subscribe", function() { with(this) {
|
221
|
+
it("publishes an event", function() { with(this) {
|
222
|
+
expect_event("alice", "subscribe", ["/messages/foo"])
|
223
|
+
subscribe("alice", "/messages/foo")
|
224
|
+
}})
|
225
|
+
|
226
|
+
describe("when the client is subscribed to the channel", function() { with(this) {
|
227
|
+
before(function() { this.subscribe("alice", "/messages/foo") })
|
228
|
+
|
229
|
+
it("does not publish an event", function() { with(this) {
|
230
|
+
expect_no_event("alice", "subscribe", ["/messages/foo"])
|
231
|
+
subscribe("alice", "/messages/foo")
|
232
|
+
}})
|
233
|
+
}})
|
234
|
+
}})
|
235
|
+
|
236
|
+
|
237
|
+
describe("unsubscribe", function() { with(this) {
|
238
|
+
before(function() { this.subscribe("alice", "/messages/bar") })
|
239
|
+
|
240
|
+
it("does not publish an event", function() { with(this) {
|
241
|
+
expect_no_event("alice", "unsubscribe", ["/messages/foo"])
|
242
|
+
unsubscribe("alice", "/messages/foo")
|
243
|
+
}})
|
244
|
+
|
245
|
+
describe("when the client is subscribed to the channel", function() { with(this) {
|
246
|
+
before(function() { this.subscribe("alice", "/messages/foo") })
|
247
|
+
|
248
|
+
it("publishes an event", function() { with(this) {
|
249
|
+
expect_event("alice", "unsubscribe", ["/messages/foo"])
|
250
|
+
unsubscribe("alice", "/messages/foo")
|
251
|
+
}})
|
173
252
|
}})
|
174
253
|
}})
|
175
254
|
|
@@ -188,6 +267,16 @@ JS.ENV.EngineSpec = JS.Test.describe("Pub/sub engines", function() { with(this)
|
|
188
267
|
expect_no_message("bob")
|
189
268
|
expect_no_message("carol")
|
190
269
|
}})
|
270
|
+
|
271
|
+
it("publishes a :publish event with a clientId", function() { with(this) {
|
272
|
+
expect_event("bob", "publish", ["/messages/foo", "ok"])
|
273
|
+
publish_by("bob", message)
|
274
|
+
}})
|
275
|
+
|
276
|
+
it("publishes a :publish event with no clientId", function() { with(this) {
|
277
|
+
expect_event(null, "publish", ["/messages/foo", "ok"])
|
278
|
+
publish(message)
|
279
|
+
}})
|
191
280
|
}})
|
192
281
|
|
193
282
|
describe("with a subscriber", function() { with(this) {
|
@@ -205,6 +294,11 @@ JS.ENV.EngineSpec = JS.Test.describe("Pub/sub engines", function() { with(this)
|
|
205
294
|
publish(message)
|
206
295
|
expect_message("alice", [message])
|
207
296
|
}})
|
297
|
+
|
298
|
+
it("publishes a :publish event with a clientId", function() { with(this) {
|
299
|
+
expect_event("bob", "publish", ["/messages/foo", "ok"])
|
300
|
+
publish_by("bob", message)
|
301
|
+
}})
|
208
302
|
}})
|
209
303
|
|
210
304
|
describe("with a subscriber that is removed", function() { with(this) {
|
@@ -219,6 +313,11 @@ JS.ENV.EngineSpec = JS.Test.describe("Pub/sub engines", function() { with(this)
|
|
219
313
|
expect_no_message("bob")
|
220
314
|
expect_no_message("carol")
|
221
315
|
}})
|
316
|
+
|
317
|
+
it("publishes a :publish event with a clientId", function() { with(this) {
|
318
|
+
expect_event("bob", "publish", ["/messages/foo", "ok"])
|
319
|
+
publish_by("bob", message)
|
320
|
+
}})
|
222
321
|
}})
|
223
322
|
|
224
323
|
describe("with multiple subscribers", function() { with(this) {
|
@@ -264,6 +363,11 @@ JS.ENV.EngineSpec = JS.Test.describe("Pub/sub engines", function() { with(this)
|
|
264
363
|
expect_no_message("bob")
|
265
364
|
expect_message("carol", [message])
|
266
365
|
}})
|
366
|
+
|
367
|
+
it("delivers a unique copy of the message to each client", function() { with(this) {
|
368
|
+
publish(message)
|
369
|
+
check_different_messages("alice", "carol")
|
370
|
+
}})
|
267
371
|
}})
|
268
372
|
|
269
373
|
describe("with multiple matching subscriptions for the same client", function() { with(this) {
|
@@ -332,8 +436,17 @@ JS.ENV.EngineSpec = JS.Test.describe("Pub/sub engines", function() { with(this)
|
|
332
436
|
after(function() { this.clean_redis_db() })
|
333
437
|
|
334
438
|
itShouldBehaveLike("faye engine")
|
439
|
+
|
335
440
|
describe("distribution", function() { with(this) {
|
336
441
|
itShouldBehaveLike("distributed engine")
|
337
442
|
}})
|
443
|
+
|
444
|
+
describe("using a Unix socket", function() { with(this) {
|
445
|
+
before(function() { with(this) {
|
446
|
+
this.engineOpts.socket = "/tmp/redis.sock"
|
447
|
+
}})
|
448
|
+
|
449
|
+
itShouldBehaveLike("faye engine")
|
450
|
+
}})
|
338
451
|
}})
|
339
452
|
}})
|
@@ -5,13 +5,11 @@ JS.ENV.NodeAdapterSteps = JS.Test.asyncSteps({
|
|
5
5
|
start_server: function(port, resume) {
|
6
6
|
this._port = port
|
7
7
|
this._app = new Faye.NodeAdapter(this.options())
|
8
|
-
this._app.listen(port)
|
9
|
-
setTimeout(resume, 50)
|
8
|
+
this._app.listen(port, {}, resume)
|
10
9
|
},
|
11
10
|
|
12
11
|
stop_server: function(resume) {
|
13
|
-
this._app.stop()
|
14
|
-
resume()
|
12
|
+
this._app.stop(resume)
|
15
13
|
},
|
16
14
|
|
17
15
|
header: function(key, value, resume) {
|
@@ -90,18 +90,6 @@ JS.ENV.Server.HandshakeSpec = JS.Test.describe("Server handshake", function() {
|
|
90
90
|
}, response)
|
91
91
|
})
|
92
92
|
}})
|
93
|
-
|
94
|
-
it("returns a successful response for local clients", function() { with(this) {
|
95
|
-
expect(engine, "createClient").yields(["clientid"])
|
96
|
-
server.handshake(message, true, function(response) {
|
97
|
-
assertEqual({
|
98
|
-
channel: "/meta/handshake",
|
99
|
-
successful: true,
|
100
|
-
version: "1.0",
|
101
|
-
clientId: "clientid"
|
102
|
-
}, response)
|
103
|
-
})
|
104
|
-
}})
|
105
93
|
}})
|
106
94
|
|
107
95
|
describe("with no matching supportedConnectionTypes", function() { with(this) {
|
@@ -1,24 +1,32 @@
|
|
1
1
|
JS.ENV.IntegrationSteps = JS.Test.asyncSteps({
|
2
|
-
server: function(port, callback) {
|
3
|
-
|
4
|
-
|
2
|
+
server: function(port, ssl, callback) {
|
3
|
+
var shared = __dirname + '/../../../examples/shared',
|
4
|
+
|
5
|
+
options = ssl
|
6
|
+
? { key: shared + '/server.key', cert: shared + '/server.crt' }
|
7
|
+
: null
|
8
|
+
|
9
|
+
this._adapter = new Faye.NodeAdapter({mount: "/bayeux", timeout: 2})
|
5
10
|
this._port = port
|
6
|
-
|
11
|
+
this._secure = ssl
|
12
|
+
this._adapter.listen(port, options, callback)
|
7
13
|
},
|
8
14
|
|
9
15
|
stop: function(callback) {
|
10
|
-
this.
|
11
|
-
|
16
|
+
for (var id in this._clients) this._clients[id].disconnect()
|
17
|
+
var self = this
|
18
|
+
setTimeout(function() { self._adapter.stop(callback) }, 100)
|
12
19
|
},
|
13
20
|
|
14
21
|
client: function(name, channels, callback) {
|
22
|
+
var scheme = this._secure ? "https" : "http"
|
15
23
|
this._clients = this._clients || {}
|
16
24
|
this._inboxes = this._inboxes || {}
|
17
|
-
this._clients[name] = new Faye.Client("
|
25
|
+
this._clients[name] = new Faye.Client(scheme + "://0.0.0.0:" + this._port + "/bayeux")
|
18
26
|
this._inboxes[name] = {}
|
19
27
|
|
20
28
|
var n = channels.length
|
21
|
-
if (n === 0) return callback
|
29
|
+
if (n === 0) return this._clients[name].connect(callback)
|
22
30
|
|
23
31
|
Faye.each(channels, function(channel) {
|
24
32
|
var subscription = this._clients[name].subscribe(channel, function(message) {
|
@@ -47,32 +55,69 @@ JS.ENV.IntegrationSteps = JS.Test.asyncSteps({
|
|
47
55
|
JS.ENV.Server.IntegrationSpec = JS.Test.describe("Server integration", function() { with(this) {
|
48
56
|
include(IntegrationSteps)
|
49
57
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
58
|
+
sharedExamplesFor("message bus", function() { with(this) {
|
59
|
+
before(function() { with(this) {
|
60
|
+
server(8000, serverOptions.ssl)
|
61
|
+
client("alice", [])
|
62
|
+
client("bob", ["/foo"])
|
63
|
+
}})
|
64
|
+
|
65
|
+
after(function() { this.stop() })
|
66
|
+
|
67
|
+
it("delivers a message between clients", function() { with(this) {
|
68
|
+
publish("alice", "/foo", {hello: "world"})
|
69
|
+
check_inbox("bob", "/foo", [{hello: "world"}])
|
70
|
+
}})
|
71
|
+
|
72
|
+
it("does not deliver messages for unsubscribed channels", function() { with(this) {
|
73
|
+
publish("alice", "/bar", {hello: "world"})
|
74
|
+
check_inbox("bob", "/foo", [])
|
75
|
+
}})
|
76
|
+
|
77
|
+
it("delivers multiple messages", function() { with(this) {
|
78
|
+
publish("alice", "/foo", {hello: "world"})
|
79
|
+
publish("alice", "/foo", {hello: "world"})
|
80
|
+
check_inbox("bob", "/foo", [{hello: "world"},{hello: "world"}])
|
81
|
+
}})
|
82
|
+
|
83
|
+
it("delivers multibyte strings", function() { with(this) {
|
84
|
+
publish("alice", "/foo", {hello: "Apple = "})
|
85
|
+
check_inbox("bob", "/foo", [{hello: "Apple = "}])
|
86
|
+
}})
|
61
87
|
}})
|
62
88
|
|
63
|
-
|
64
|
-
|
65
|
-
|
89
|
+
sharedExamplesFor("network transports", function() { with(this) {
|
90
|
+
describe("with HTTP transport", function() { with(this) {
|
91
|
+
before(function() { with(this) {
|
92
|
+
stub(Faye.Transport.WebSocket, "isUsable").yields([false])
|
93
|
+
}})
|
94
|
+
|
95
|
+
itShouldBehaveLike("message bus")
|
96
|
+
}})
|
97
|
+
|
98
|
+
describe("with WebSocket transport", function() { with(this) {
|
99
|
+
before(function() { with(this) {
|
100
|
+
stub(Faye.Transport.WebSocket, "isUsable").yields([true])
|
101
|
+
}})
|
102
|
+
|
103
|
+
itShouldBehaveLike("message bus")
|
104
|
+
}})
|
66
105
|
}})
|
67
106
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
107
|
+
describe("with HTTP server", function() { with(this) {
|
108
|
+
before(function() { with(this) {
|
109
|
+
this.serverOptions = {ssl: false}
|
110
|
+
}})
|
111
|
+
|
112
|
+
itShouldBehaveLike("network transports")
|
72
113
|
}})
|
73
114
|
|
74
|
-
|
75
|
-
|
76
|
-
|
115
|
+
describe("with HTTPS server", function() { with(this) {
|
116
|
+
before(function() { with(this) {
|
117
|
+
this.serverOptions = {ssl: true}
|
118
|
+
}})
|
119
|
+
|
120
|
+
itShouldBehaveLike("network transports")
|
77
121
|
}})
|
78
122
|
}})
|
123
|
+
|