faye 0.8.11 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of faye might be problematic. Click here for more details.
- data/{History.txt → CHANGELOG.md} +126 -105
- data/README.md +36 -0
- data/lib/faye-browser-min.js +2 -1
- data/lib/faye-browser-min.js.map +1 -8
- data/lib/faye-browser.js +923 -607
- data/lib/faye.rb +11 -5
- data/lib/faye/adapters/rack_adapter.rb +80 -85
- data/lib/faye/engines/connection.rb +7 -9
- data/lib/faye/engines/memory.rb +1 -0
- data/lib/faye/engines/proxy.rb +7 -6
- data/lib/faye/mixins/deferrable.rb +15 -0
- data/lib/faye/mixins/logging.rb +11 -22
- data/lib/faye/mixins/publisher.rb +9 -20
- data/lib/faye/protocol/channel.rb +2 -1
- data/lib/faye/protocol/client.rb +70 -48
- data/lib/faye/protocol/envelope.rb +24 -0
- data/lib/faye/protocol/extensible.rb +7 -4
- data/lib/faye/protocol/publication.rb +1 -1
- data/lib/faye/protocol/server.rb +8 -11
- data/lib/faye/protocol/socket.rb +6 -4
- data/lib/faye/protocol/subscription.rb +1 -1
- data/lib/faye/transport/http.rb +20 -27
- data/lib/faye/transport/local.rb +5 -5
- data/lib/faye/transport/transport.rb +42 -12
- data/lib/faye/transport/web_socket.rb +71 -38
- metadata +169 -137
- checksums.yaml +0 -7
- data/README.rdoc +0 -83
- data/spec/browser.html +0 -45
- data/spec/encoding_helper.rb +0 -7
- data/spec/install.sh +0 -78
- data/spec/javascript/channel_spec.js +0 -15
- data/spec/javascript/client_spec.js +0 -729
- data/spec/javascript/dispatcher_spec.js +0 -122
- data/spec/javascript/engine/memory_spec.js +0 -7
- data/spec/javascript/engine_spec.js +0 -417
- data/spec/javascript/faye_spec.js +0 -34
- data/spec/javascript/grammar_spec.js +0 -66
- data/spec/javascript/node_adapter_spec.js +0 -314
- data/spec/javascript/publisher_spec.js +0 -27
- data/spec/javascript/server/connect_spec.js +0 -168
- data/spec/javascript/server/disconnect_spec.js +0 -121
- data/spec/javascript/server/extensions_spec.js +0 -60
- data/spec/javascript/server/handshake_spec.js +0 -145
- data/spec/javascript/server/integration_spec.js +0 -131
- data/spec/javascript/server/publish_spec.js +0 -85
- data/spec/javascript/server/subscribe_spec.js +0 -247
- data/spec/javascript/server/unsubscribe_spec.js +0 -245
- data/spec/javascript/server_spec.js +0 -121
- data/spec/javascript/transport_spec.js +0 -135
- data/spec/node.js +0 -55
- data/spec/phantom.js +0 -17
- data/spec/ruby/channel_spec.rb +0 -17
- data/spec/ruby/client_spec.rb +0 -741
- data/spec/ruby/engine/memory_spec.rb +0 -7
- data/spec/ruby/engine_examples.rb +0 -427
- data/spec/ruby/faye_spec.rb +0 -30
- data/spec/ruby/grammar_spec.rb +0 -68
- data/spec/ruby/publisher_spec.rb +0 -27
- data/spec/ruby/rack_adapter_spec.rb +0 -241
- data/spec/ruby/server/connect_spec.rb +0 -170
- data/spec/ruby/server/disconnect_spec.rb +0 -120
- data/spec/ruby/server/extensions_spec.rb +0 -68
- data/spec/ruby/server/handshake_spec.rb +0 -143
- data/spec/ruby/server/integration_spec.rb +0 -133
- data/spec/ruby/server/publish_spec.rb +0 -81
- data/spec/ruby/server/subscribe_spec.rb +0 -247
- data/spec/ruby/server/unsubscribe_spec.rb +0 -247
- data/spec/ruby/server_spec.rb +0 -121
- data/spec/ruby/transport_spec.rb +0 -136
- data/spec/spec_helper.rb +0 -11
- data/spec/testswarm +0 -42
- data/spec/thin_proxy.rb +0 -37
@@ -1,122 +0,0 @@
|
|
1
|
-
DispatcherSpec = JS.Test.describe("Dispatcher", function() { with(this) {
|
2
|
-
include(JS.Test.FakeClock)
|
3
|
-
|
4
|
-
before(function() { with(this) {
|
5
|
-
this.client = {}
|
6
|
-
this.endpoint = "http://localhost/"
|
7
|
-
this.transport = {endpoint: Faye.URI.parse(endpoint)}
|
8
|
-
|
9
|
-
stub(Faye.Transport, "get").yields([transport])
|
10
|
-
|
11
|
-
this.dispatcher = new Faye.Dispatcher(client, endpoint, options())
|
12
|
-
|
13
|
-
clock.stub()
|
14
|
-
}})
|
15
|
-
|
16
|
-
after(function() { with(this) {
|
17
|
-
clock.reset()
|
18
|
-
}})
|
19
|
-
|
20
|
-
define("options", function() {
|
21
|
-
return {}
|
22
|
-
})
|
23
|
-
|
24
|
-
describe("endpointFor", function() { with(this) {
|
25
|
-
define("options", function() {
|
26
|
-
return {
|
27
|
-
endpoints: {websocket: "http://sockets/"}
|
28
|
-
}
|
29
|
-
})
|
30
|
-
|
31
|
-
it("returns the main endpoint for unspecified connection types", function() { with(this) {
|
32
|
-
assertEqual( "http://localhost/", dispatcher.endpointFor("long-polling").href )
|
33
|
-
}})
|
34
|
-
|
35
|
-
it("returns an alternate endpoint where specified", function() { with(this) {
|
36
|
-
assertEqual( "http://sockets/", dispatcher.endpointFor("websocket").href )
|
37
|
-
}})
|
38
|
-
}})
|
39
|
-
|
40
|
-
describe("selectTransport", function() { with(this) {
|
41
|
-
before(function() { with(this) {
|
42
|
-
this.connectionTypes = ["long-polling", "callback-polling", "websocket"]
|
43
|
-
}})
|
44
|
-
|
45
|
-
it("asks Transport to select one of the given transports", function() { with(this) {
|
46
|
-
expect(Faye.Transport, "get").given(dispatcher, connectionTypes, []).yields([transport])
|
47
|
-
dispatcher.selectTransport(connectionTypes)
|
48
|
-
}})
|
49
|
-
|
50
|
-
it("asks Transport not to select disabled transports", function() { with(this) {
|
51
|
-
dispatcher.disable("websocket")
|
52
|
-
expect(Faye.Transport, "get").given(dispatcher, connectionTypes, ["websocket"]).yields([transport])
|
53
|
-
dispatcher.selectTransport(connectionTypes)
|
54
|
-
}})
|
55
|
-
|
56
|
-
it("sets connectionType on the dispatcher", function() { with(this) {
|
57
|
-
transport.connectionType = "transport-connection-type"
|
58
|
-
dispatcher.selectTransport(connectionTypes)
|
59
|
-
assertEqual( "transport-connection-type", dispatcher.connectionType )
|
60
|
-
}})
|
61
|
-
|
62
|
-
it("closes the existing transport if a new one is selected", function() { with(this) {
|
63
|
-
var oldTransport = {endpoint: Faye.URI.parse(endpoint)}
|
64
|
-
stub(Faye.Transport, "get").given(dispatcher, ["long-polling"], []).yields([oldTransport])
|
65
|
-
dispatcher.selectTransport(["long-polling"])
|
66
|
-
|
67
|
-
expect(oldTransport, "close").exactly(1)
|
68
|
-
dispatcher.selectTransport(connectionTypes)
|
69
|
-
}})
|
70
|
-
|
71
|
-
it("does not close the existing transport if the same one is selected", function() { with(this) {
|
72
|
-
dispatcher.selectTransport(["long-polling"])
|
73
|
-
|
74
|
-
expect(transport, "close").exactly(0)
|
75
|
-
dispatcher.selectTransport(connectionTypes)
|
76
|
-
}})
|
77
|
-
}})
|
78
|
-
|
79
|
-
describe("messaging management", function() { with(this) {
|
80
|
-
before(function() { with(this) {
|
81
|
-
this.message = {id: 1}
|
82
|
-
this.request = {}
|
83
|
-
|
84
|
-
stub(transport, "close")
|
85
|
-
stub(transport, "sendMessage")
|
86
|
-
|
87
|
-
dispatcher.selectTransport([])
|
88
|
-
}})
|
89
|
-
|
90
|
-
describe("sendMessage", function() { with(this) {
|
91
|
-
it("does not send a message to the transport if closed", function() { with(this) {
|
92
|
-
dispatcher.close()
|
93
|
-
expect(transport, "sendMessage").exactly(0)
|
94
|
-
dispatcher.sendMessage(message)
|
95
|
-
}})
|
96
|
-
|
97
|
-
it("sends a message to the transport", function() { with(this) {
|
98
|
-
expect(transport, "sendMessage").given({id: 1}).exactly(1)
|
99
|
-
dispatcher.sendMessage(message)
|
100
|
-
}})
|
101
|
-
|
102
|
-
it("sends several different messages to the transport", function() { with(this) {
|
103
|
-
expect(transport, "sendMessage").given({id: 1}).exactly(1)
|
104
|
-
expect(transport, "sendMessage").given({id: 2}).exactly(1)
|
105
|
-
dispatcher.sendMessage({id: 1})
|
106
|
-
dispatcher.sendMessage({id: 2})
|
107
|
-
}})
|
108
|
-
|
109
|
-
it("does not resend a message if it's already being sent", function() { with(this) {
|
110
|
-
expect(transport, "sendMessage").given({id: 1}).exactly(1)
|
111
|
-
dispatcher.sendMessage(message)
|
112
|
-
dispatcher.sendMessage(message)
|
113
|
-
}})
|
114
|
-
|
115
|
-
it("sets a timeout to fail the message", function() { with(this) {
|
116
|
-
dispatcher.sendMessage(message, 25)
|
117
|
-
expect(dispatcher, "handleError").given({id: 1}, false).exactly(1)
|
118
|
-
clock.tick(25000)
|
119
|
-
}})
|
120
|
-
}})
|
121
|
-
}})
|
122
|
-
}})
|
@@ -1,417 +0,0 @@
|
|
1
|
-
JS.ENV.EngineSteps = JS.Test.asyncSteps({
|
2
|
-
create_client: function(name, resume) {
|
3
|
-
var inboxes = this._inboxes = this._inboxes || {}
|
4
|
-
var clients = this._clients = this._clients || {}
|
5
|
-
this.engine.createClient(function(clientId) {
|
6
|
-
clients[name] = clientId
|
7
|
-
inboxes[name] = inboxes[name] || []
|
8
|
-
resume()
|
9
|
-
})
|
10
|
-
},
|
11
|
-
|
12
|
-
connect: function(name, engine, resume) {
|
13
|
-
var clientId = this._clients[name]
|
14
|
-
var inboxes = this._inboxes
|
15
|
-
engine.connect(clientId, {}, function(messages) {
|
16
|
-
for (var i = 0, n = messages.length; i < n; i++) {
|
17
|
-
delete messages[i].id
|
18
|
-
inboxes[name].push(messages[i])
|
19
|
-
}
|
20
|
-
})
|
21
|
-
setTimeout(resume, 10)
|
22
|
-
},
|
23
|
-
|
24
|
-
destroy_client: function(name, resume) {
|
25
|
-
this.engine.destroyClient(this._clients[name], resume)
|
26
|
-
},
|
27
|
-
|
28
|
-
check_client_id: function(name, pattern, resume) {
|
29
|
-
this.assertMatch(pattern, this._clients[name])
|
30
|
-
resume()
|
31
|
-
},
|
32
|
-
|
33
|
-
check_num_clients: function(n, resume) {
|
34
|
-
var ids = new JS.Set()
|
35
|
-
for (var key in this._clients) ids.add(this._clients[key])
|
36
|
-
this.assertEqual(n, ids.count())
|
37
|
-
resume()
|
38
|
-
},
|
39
|
-
|
40
|
-
check_client_exists: function(name, exists, resume) {
|
41
|
-
var tc = this
|
42
|
-
tc.engine.clientExists(tc._clients[name], function(actual) {
|
43
|
-
tc.assertEqual(exists, actual)
|
44
|
-
resume()
|
45
|
-
})
|
46
|
-
},
|
47
|
-
|
48
|
-
subscribe: function(name, channel, resume) {
|
49
|
-
this.engine.subscribe(this._clients[name], channel, resume)
|
50
|
-
},
|
51
|
-
|
52
|
-
unsubscribe: function(name, channel, resume) {
|
53
|
-
this.engine.unsubscribe(this._clients[name], channel, resume)
|
54
|
-
},
|
55
|
-
|
56
|
-
publish: function(messages, resume) {
|
57
|
-
messages = [].concat(messages)
|
58
|
-
for (var i = 0, n = messages.length; i < n; i++) {
|
59
|
-
var message = Faye.extend({id: Faye.random()}, messages[i])
|
60
|
-
this.engine.publish(message)
|
61
|
-
}
|
62
|
-
setTimeout(resume, 20)
|
63
|
-
},
|
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
|
-
|
71
|
-
ping: function(name, resume) {
|
72
|
-
this.engine.ping(this._clients[name])
|
73
|
-
resume()
|
74
|
-
},
|
75
|
-
|
76
|
-
clock_tick: function(time, resume) {
|
77
|
-
setTimeout(resume, time)
|
78
|
-
},
|
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
|
-
|
98
|
-
expect_message: function(name, messages, resume) {
|
99
|
-
this.assertEqual(messages, this._inboxes[name])
|
100
|
-
resume()
|
101
|
-
},
|
102
|
-
|
103
|
-
expect_no_message: function(name, resume) {
|
104
|
-
this.assertEqual([], this._inboxes[name])
|
105
|
-
resume()
|
106
|
-
},
|
107
|
-
|
108
|
-
check_different_messages: function(a, b, resume) {
|
109
|
-
this.assertNotSame(this._inboxes[a][0], this._inboxes[b][0])
|
110
|
-
resume()
|
111
|
-
}
|
112
|
-
})
|
113
|
-
|
114
|
-
JS.ENV.EngineSpec = JS.Test.describe("Pub/sub engines", function() { with(this) {
|
115
|
-
sharedExamplesFor("faye engine", function() { with(this) {
|
116
|
-
include(JS.Test.Helpers)
|
117
|
-
include(EngineSteps)
|
118
|
-
|
119
|
-
define("create_engine", function() { with(this) {
|
120
|
-
var opts = Faye.extend(options(), engineOpts)
|
121
|
-
return new Faye.Engine.Proxy(opts)
|
122
|
-
}})
|
123
|
-
|
124
|
-
define("options", function() { return {timeout: 1} })
|
125
|
-
|
126
|
-
before(function() { with(this) {
|
127
|
-
this.engine = create_engine()
|
128
|
-
create_client("alice")
|
129
|
-
create_client("bob")
|
130
|
-
create_client("carol")
|
131
|
-
}})
|
132
|
-
|
133
|
-
describe("createClient", function() { with(this) {
|
134
|
-
it("returns a client id", function() { with(this) {
|
135
|
-
create_client("dave")
|
136
|
-
check_client_id("dave", /^[a-z0-9]+$/)
|
137
|
-
}})
|
138
|
-
|
139
|
-
it("returns a different id every time", function() { with(this) {
|
140
|
-
$R(1,7).forEach(function(i) { create_client("client" + i) })
|
141
|
-
check_num_clients(10)
|
142
|
-
}})
|
143
|
-
|
144
|
-
it("publishes an event", function() { with(this) {
|
145
|
-
expect(engine, "trigger").given("handshake", match(/^[a-z0-9]+$/))
|
146
|
-
create_client("dave")
|
147
|
-
}})
|
148
|
-
}})
|
149
|
-
|
150
|
-
describe("clientExists", function() { with(this) {
|
151
|
-
it("returns true if the client id exists", function() { with(this) {
|
152
|
-
check_client_exists("alice", true)
|
153
|
-
}})
|
154
|
-
|
155
|
-
it("returns false if the client id does not exist", function() { with(this) {
|
156
|
-
check_client_exists("anything", false)
|
157
|
-
}})
|
158
|
-
}})
|
159
|
-
|
160
|
-
describe("ping", function() { with(this) {
|
161
|
-
define("options", function() { return {timeout: 0.3, gc: 0.08} })
|
162
|
-
|
163
|
-
it("removes a client if it does not ping often enough", function() { with(this) {
|
164
|
-
clock_tick(700)
|
165
|
-
check_client_exists("alice", false)
|
166
|
-
}})
|
167
|
-
|
168
|
-
it("prolongs the life of a client", function() { with(this) {
|
169
|
-
clock_tick(450)
|
170
|
-
ping("alice")
|
171
|
-
clock_tick(450)
|
172
|
-
check_client_exists("alice", true)
|
173
|
-
clock_tick(450)
|
174
|
-
check_client_exists("alice", false)
|
175
|
-
}})
|
176
|
-
}})
|
177
|
-
|
178
|
-
describe("destroyClient", function() { with(this) {
|
179
|
-
it("removes the given client", function() { with(this) {
|
180
|
-
destroy_client("alice")
|
181
|
-
check_client_exists("alice", false)
|
182
|
-
}})
|
183
|
-
|
184
|
-
it("publishes an event", function() { with(this) {
|
185
|
-
expect_event("alice", "disconnect", [])
|
186
|
-
destroy_client("alice")
|
187
|
-
}})
|
188
|
-
|
189
|
-
describe("when the client has subscriptions", function() { with(this) {
|
190
|
-
before(function() { with(this) {
|
191
|
-
this.message = {"channel": "/messages/foo", "data": "ok"}
|
192
|
-
subscribe("alice", "/messages/foo")
|
193
|
-
}})
|
194
|
-
|
195
|
-
it("stops the client receiving messages", function() { with(this) {
|
196
|
-
connect("alice", engine)
|
197
|
-
destroy_client("alice")
|
198
|
-
publish(message)
|
199
|
-
expect_no_message("alice")
|
200
|
-
}})
|
201
|
-
|
202
|
-
it("publishes an event", function() { with(this) {
|
203
|
-
expect_event("alice", "disconnect", [])
|
204
|
-
destroy_client("alice")
|
205
|
-
}})
|
206
|
-
}})
|
207
|
-
}})
|
208
|
-
|
209
|
-
describe("subscribe", function() { with(this) {
|
210
|
-
it("publishes an event", function() { with(this) {
|
211
|
-
expect_event("alice", "subscribe", ["/messages/foo"])
|
212
|
-
subscribe("alice", "/messages/foo")
|
213
|
-
}})
|
214
|
-
|
215
|
-
describe("when the client is subscribed to the channel", function() { with(this) {
|
216
|
-
before(function() { this.subscribe("alice", "/messages/foo") })
|
217
|
-
|
218
|
-
it("does not publish an event", function() { with(this) {
|
219
|
-
expect_no_event("alice", "subscribe", ["/messages/foo"])
|
220
|
-
subscribe("alice", "/messages/foo")
|
221
|
-
}})
|
222
|
-
}})
|
223
|
-
}})
|
224
|
-
|
225
|
-
|
226
|
-
describe("unsubscribe", function() { with(this) {
|
227
|
-
before(function() { this.subscribe("alice", "/messages/bar") })
|
228
|
-
|
229
|
-
it("does not publish an event", function() { with(this) {
|
230
|
-
expect_no_event("alice", "unsubscribe", ["/messages/foo"])
|
231
|
-
unsubscribe("alice", "/messages/foo")
|
232
|
-
}})
|
233
|
-
|
234
|
-
describe("when the client is subscribed to the channel", function() { with(this) {
|
235
|
-
before(function() { this.subscribe("alice", "/messages/foo") })
|
236
|
-
|
237
|
-
it("publishes an event", function() { with(this) {
|
238
|
-
expect_event("alice", "unsubscribe", ["/messages/foo"])
|
239
|
-
unsubscribe("alice", "/messages/foo")
|
240
|
-
}})
|
241
|
-
}})
|
242
|
-
}})
|
243
|
-
|
244
|
-
describe("publish", function() { with(this) {
|
245
|
-
before(function() { with(this) {
|
246
|
-
this.message = {"channel": "/messages/foo", "data": "ok", "blank": null}
|
247
|
-
connect("alice", engine)
|
248
|
-
connect("bob", engine)
|
249
|
-
connect("carol", engine)
|
250
|
-
}})
|
251
|
-
|
252
|
-
describe("with no subscriptions", function() { with(this) {
|
253
|
-
it("delivers no messages", function() { with(this) {
|
254
|
-
publish(message)
|
255
|
-
expect_no_message("alice")
|
256
|
-
expect_no_message("bob")
|
257
|
-
expect_no_message("carol")
|
258
|
-
}})
|
259
|
-
|
260
|
-
it("publishes a :publish event with a clientId", function() { with(this) {
|
261
|
-
expect_event("bob", "publish", ["/messages/foo", "ok"])
|
262
|
-
publish_by("bob", message)
|
263
|
-
}})
|
264
|
-
|
265
|
-
it("publishes a :publish event with no clientId", function() { with(this) {
|
266
|
-
expect_event(null, "publish", ["/messages/foo", "ok"])
|
267
|
-
publish(message)
|
268
|
-
}})
|
269
|
-
}})
|
270
|
-
|
271
|
-
describe("with a subscriber", function() { with(this) {
|
272
|
-
before(function() { with(this) {
|
273
|
-
subscribe("alice", "/messages/foo")
|
274
|
-
}})
|
275
|
-
|
276
|
-
it("delivers multibyte messages correctly", function() { with(this) {
|
277
|
-
message.data = "Apple = "
|
278
|
-
publish(message)
|
279
|
-
expect_message("alice", [message])
|
280
|
-
}})
|
281
|
-
|
282
|
-
it("delivers messages to the subscribed client", function() { with(this) {
|
283
|
-
publish(message)
|
284
|
-
expect_message("alice", [message])
|
285
|
-
}})
|
286
|
-
|
287
|
-
it("publishes a :publish event with a clientId", function() { with(this) {
|
288
|
-
expect_event("bob", "publish", ["/messages/foo", "ok"])
|
289
|
-
publish_by("bob", message)
|
290
|
-
}})
|
291
|
-
}})
|
292
|
-
|
293
|
-
describe("with a subscriber that is removed", function() { with(this) {
|
294
|
-
before(function() { with(this) {
|
295
|
-
subscribe("alice", "/messages/foo")
|
296
|
-
unsubscribe("alice", "/messages/foo")
|
297
|
-
}})
|
298
|
-
|
299
|
-
it("does not deliver messages to unsubscribed clients", function() { with(this) {
|
300
|
-
publish(message)
|
301
|
-
expect_no_message("alice")
|
302
|
-
expect_no_message("bob")
|
303
|
-
expect_no_message("carol")
|
304
|
-
}})
|
305
|
-
|
306
|
-
it("publishes a :publish event with a clientId", function() { with(this) {
|
307
|
-
expect_event("bob", "publish", ["/messages/foo", "ok"])
|
308
|
-
publish_by("bob", message)
|
309
|
-
}})
|
310
|
-
}})
|
311
|
-
|
312
|
-
describe("with multiple subscribers", function() { with(this) {
|
313
|
-
before(function() { with(this) {
|
314
|
-
subscribe("alice", "/messages/foo")
|
315
|
-
subscribe("bob", "/messages/bar")
|
316
|
-
subscribe("carol", "/messages/foo")
|
317
|
-
}})
|
318
|
-
|
319
|
-
it("delivers messages to the subscribed clients", function() { with(this) {
|
320
|
-
publish(message)
|
321
|
-
expect_message("alice", [message])
|
322
|
-
expect_no_message("bob")
|
323
|
-
expect_message("carol", [message])
|
324
|
-
}})
|
325
|
-
}})
|
326
|
-
|
327
|
-
describe("with a single wildcard", function() { with(this) {
|
328
|
-
before(function() { with(this) {
|
329
|
-
subscribe("alice", "/messages/*")
|
330
|
-
subscribe("bob", "/messages/bar")
|
331
|
-
subscribe("carol", "/*")
|
332
|
-
}})
|
333
|
-
|
334
|
-
it("delivers messages to matching subscriptions", function() { with(this) {
|
335
|
-
publish(message)
|
336
|
-
expect_message("alice", [message])
|
337
|
-
expect_no_message("bob")
|
338
|
-
expect_no_message("carol")
|
339
|
-
}})
|
340
|
-
}})
|
341
|
-
|
342
|
-
describe("with a double wildcard", function() { with(this) {
|
343
|
-
before(function() { with(this) {
|
344
|
-
subscribe("alice", "/messages/**")
|
345
|
-
subscribe("bob", "/messages/bar")
|
346
|
-
subscribe("carol", "/**")
|
347
|
-
}})
|
348
|
-
|
349
|
-
it("delivers messages to matching subscriptions", function() { with(this) {
|
350
|
-
publish(message)
|
351
|
-
expect_message("alice", [message])
|
352
|
-
expect_no_message("bob")
|
353
|
-
expect_message("carol", [message])
|
354
|
-
}})
|
355
|
-
|
356
|
-
it("delivers a unique copy of the message to each client", function() { with(this) {
|
357
|
-
publish(message)
|
358
|
-
check_different_messages("alice", "carol")
|
359
|
-
}})
|
360
|
-
}})
|
361
|
-
|
362
|
-
describe("with multiple matching subscriptions for the same client", function() { with(this) {
|
363
|
-
before(function() { with(this) {
|
364
|
-
subscribe("alice", "/messages/*")
|
365
|
-
subscribe("alice", "/messages/foo")
|
366
|
-
}})
|
367
|
-
|
368
|
-
it("delivers each message once to each client", function() { with(this) {
|
369
|
-
publish(message)
|
370
|
-
expect_message("alice", [message])
|
371
|
-
}})
|
372
|
-
|
373
|
-
it("delivers the message as many times as it is published", function() { with(this) {
|
374
|
-
publish([message, message])
|
375
|
-
expect_message("alice", [message, message])
|
376
|
-
}})
|
377
|
-
}})
|
378
|
-
}})
|
379
|
-
}})
|
380
|
-
|
381
|
-
sharedBehavior("distributed engine", function() { with(this) {
|
382
|
-
include(JS.Test.Helpers)
|
383
|
-
include(EngineSteps)
|
384
|
-
|
385
|
-
define("create_engine", function() { with(this) {
|
386
|
-
var opts = Faye.extend(options(), engineOpts)
|
387
|
-
return new Faye.Engine.Proxy(opts)
|
388
|
-
}})
|
389
|
-
|
390
|
-
define("options", function() { return {timeout: 1} })
|
391
|
-
|
392
|
-
before(function() { with(this) {
|
393
|
-
this.left = create_engine()
|
394
|
-
this.right = create_engine()
|
395
|
-
this.engine = left
|
396
|
-
|
397
|
-
create_client("alice")
|
398
|
-
create_client("bob")
|
399
|
-
|
400
|
-
connect("alice", left)
|
401
|
-
}})
|
402
|
-
|
403
|
-
describe("publish", function() { with(this) {
|
404
|
-
before(function() { with(this) {
|
405
|
-
subscribe("alice", "/foo")
|
406
|
-
publish({channel: "/foo", data: "first"})
|
407
|
-
}})
|
408
|
-
|
409
|
-
it("only delivers each message once", function() { with(this) {
|
410
|
-
expect_message("alice", [{channel: "/foo", data: "first"}])
|
411
|
-
publish({channel: "/foo", data: "second"})
|
412
|
-
connect("alice", right)
|
413
|
-
expect_message("alice", [{channel: "/foo", data: "first"}, {channel: "/foo", data: "second"}])
|
414
|
-
}})
|
415
|
-
}})
|
416
|
-
}})
|
417
|
-
}})
|