faye 0.8.11 → 1.0.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.

Files changed (73) hide show
  1. data/{History.txt → CHANGELOG.md} +126 -105
  2. data/README.md +36 -0
  3. data/lib/faye-browser-min.js +2 -1
  4. data/lib/faye-browser-min.js.map +1 -8
  5. data/lib/faye-browser.js +923 -607
  6. data/lib/faye.rb +11 -5
  7. data/lib/faye/adapters/rack_adapter.rb +80 -85
  8. data/lib/faye/engines/connection.rb +7 -9
  9. data/lib/faye/engines/memory.rb +1 -0
  10. data/lib/faye/engines/proxy.rb +7 -6
  11. data/lib/faye/mixins/deferrable.rb +15 -0
  12. data/lib/faye/mixins/logging.rb +11 -22
  13. data/lib/faye/mixins/publisher.rb +9 -20
  14. data/lib/faye/protocol/channel.rb +2 -1
  15. data/lib/faye/protocol/client.rb +70 -48
  16. data/lib/faye/protocol/envelope.rb +24 -0
  17. data/lib/faye/protocol/extensible.rb +7 -4
  18. data/lib/faye/protocol/publication.rb +1 -1
  19. data/lib/faye/protocol/server.rb +8 -11
  20. data/lib/faye/protocol/socket.rb +6 -4
  21. data/lib/faye/protocol/subscription.rb +1 -1
  22. data/lib/faye/transport/http.rb +20 -27
  23. data/lib/faye/transport/local.rb +5 -5
  24. data/lib/faye/transport/transport.rb +42 -12
  25. data/lib/faye/transport/web_socket.rb +71 -38
  26. metadata +169 -137
  27. checksums.yaml +0 -7
  28. data/README.rdoc +0 -83
  29. data/spec/browser.html +0 -45
  30. data/spec/encoding_helper.rb +0 -7
  31. data/spec/install.sh +0 -78
  32. data/spec/javascript/channel_spec.js +0 -15
  33. data/spec/javascript/client_spec.js +0 -729
  34. data/spec/javascript/dispatcher_spec.js +0 -122
  35. data/spec/javascript/engine/memory_spec.js +0 -7
  36. data/spec/javascript/engine_spec.js +0 -417
  37. data/spec/javascript/faye_spec.js +0 -34
  38. data/spec/javascript/grammar_spec.js +0 -66
  39. data/spec/javascript/node_adapter_spec.js +0 -314
  40. data/spec/javascript/publisher_spec.js +0 -27
  41. data/spec/javascript/server/connect_spec.js +0 -168
  42. data/spec/javascript/server/disconnect_spec.js +0 -121
  43. data/spec/javascript/server/extensions_spec.js +0 -60
  44. data/spec/javascript/server/handshake_spec.js +0 -145
  45. data/spec/javascript/server/integration_spec.js +0 -131
  46. data/spec/javascript/server/publish_spec.js +0 -85
  47. data/spec/javascript/server/subscribe_spec.js +0 -247
  48. data/spec/javascript/server/unsubscribe_spec.js +0 -245
  49. data/spec/javascript/server_spec.js +0 -121
  50. data/spec/javascript/transport_spec.js +0 -135
  51. data/spec/node.js +0 -55
  52. data/spec/phantom.js +0 -17
  53. data/spec/ruby/channel_spec.rb +0 -17
  54. data/spec/ruby/client_spec.rb +0 -741
  55. data/spec/ruby/engine/memory_spec.rb +0 -7
  56. data/spec/ruby/engine_examples.rb +0 -427
  57. data/spec/ruby/faye_spec.rb +0 -30
  58. data/spec/ruby/grammar_spec.rb +0 -68
  59. data/spec/ruby/publisher_spec.rb +0 -27
  60. data/spec/ruby/rack_adapter_spec.rb +0 -241
  61. data/spec/ruby/server/connect_spec.rb +0 -170
  62. data/spec/ruby/server/disconnect_spec.rb +0 -120
  63. data/spec/ruby/server/extensions_spec.rb +0 -68
  64. data/spec/ruby/server/handshake_spec.rb +0 -143
  65. data/spec/ruby/server/integration_spec.rb +0 -133
  66. data/spec/ruby/server/publish_spec.rb +0 -81
  67. data/spec/ruby/server/subscribe_spec.rb +0 -247
  68. data/spec/ruby/server/unsubscribe_spec.rb +0 -247
  69. data/spec/ruby/server_spec.rb +0 -121
  70. data/spec/ruby/transport_spec.rb +0 -136
  71. data/spec/spec_helper.rb +0 -11
  72. data/spec/testswarm +0 -42
  73. 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,7 +0,0 @@
1
- JS.ENV.Engine.MemorySpec = JS.Test.describe("Memory engine", function() { with(this) {
2
- before(function() {
3
- this.engineOpts = {type: Faye.Engine.Memory}
4
- })
5
-
6
- itShouldBehaveLike("faye engine")
7
- }})
@@ -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
- }})