spec/javascript/engine_spec.js in faye-0.8.8 vs spec/javascript/engine_spec.js in faye-0.8.9

- old
+ new

@@ -6,11 +6,11 @@ clients[name] = clientId inboxes[name] = inboxes[name] || [] resume() }) }, - + connect: function(name, engine, resume) { var clientId = this._clients[name] var inboxes = this._inboxes engine.connect(clientId, {}, function(messages) { for (var i = 0, n = messages.length; i < n; i++) { @@ -18,395 +18,395 @@ inboxes[name].push(messages[i]) } }) setTimeout(resume, 10) }, - + destroy_client: function(name, resume) { this.engine.destroyClient(this._clients[name], resume) }, - + check_client_id: function(name, pattern, resume) { this.assertMatch(pattern, this._clients[name]) resume() }, - + check_num_clients: function(n, resume) { var ids = new JS.Set() for (var key in this._clients) ids.add(this._clients[key]) this.assertEqual(n, ids.count()) resume() }, - + check_client_exists: function(name, exists, resume) { var tc = this tc.engine.clientExists(tc._clients[name], function(actual) { tc.assertEqual(exists, actual) resume() }) }, - + subscribe: function(name, channel, resume) { this.engine.subscribe(this._clients[name], channel, resume) }, - + unsubscribe: function(name, channel, resume) { this.engine.unsubscribe(this._clients[name], channel, resume) }, - + publish: function(messages, resume) { messages = [].concat(messages) for (var i = 0, n = messages.length; i < n; i++) { var message = Faye.extend({id: Faye.random()}, messages[i]) this.engine.publish(message) } setTimeout(resume, 20) }, - + publish_by: function(name, message, resume) { message = Faye.extend({clientId: this._clients[name], id: Faye.random()}, message) this.engine.publish(message) setTimeout(resume, 10) }, - + ping: function(name, resume) { this.engine.ping(this._clients[name]) resume() }, - + clock_tick: function(time, resume) { setTimeout(resume, time) }, - + expect_event: function(name, event, args, resume) { var params = [this._clients[name]].concat(args), handler = function() {} - + this.engine.bind(event, handler) this.expect(handler, "apply").given(undefined, params) resume() }, - + expect_no_event: function(name, event, args, resume) { var params = [this._clients[name]].concat(args), handler = function() {} - + this.engine.bind(event, handler) this.expect(handler, "apply").exactly(0) resume() }, - + expect_message: function(name, messages, resume) { this.assertEqual(messages, this._inboxes[name]) resume() }, - + expect_no_message: function(name, resume) { this.assertEqual([], this._inboxes[name]) resume() }, - + check_different_messages: function(a, b, resume) { this.assertNotSame(this._inboxes[a][0], this._inboxes[b][0]) resume() } }) JS.ENV.EngineSpec = JS.Test.describe("Pub/sub engines", function() { with(this) { sharedExamplesFor("faye engine", function() { with(this) { include(JS.Test.Helpers) include(EngineSteps) - + define("create_engine", function() { with(this) { var opts = Faye.extend(options(), engineOpts) return new Faye.Engine.Proxy(opts) }}) - + define("options", function() { return {timeout: 1} }) - + before(function() { with(this) { this.engine = create_engine() create_client("alice") create_client("bob") create_client("carol") }}) - + describe("createClient", function() { with(this) { it("returns a client id", function() { with(this) { create_client("dave") check_client_id("dave", /^[a-z0-9]+$/) }}) - + it("returns a different id every time", function() { with(this) { $R(1,7).forEach(function(i) { create_client("client" + i) }) check_num_clients(10) }}) - + it("publishes an event", function() { with(this) { expect(engine, "trigger").given("handshake", match(/^[a-z0-9]+$/)) create_client("dave") }}) }}) - + describe("clientExists", function() { with(this) { it("returns true if the client id exists", function() { with(this) { check_client_exists("alice", true) }}) - + it("returns false if the client id does not exist", function() { with(this) { check_client_exists("anything", false) }}) }}) - + describe("ping", function() { with(this) { define("options", function() { return {timeout: 0.3, gc: 0.08} }) - + it("removes a client if it does not ping often enough", function() { with(this) { clock_tick(700) check_client_exists("alice", false) }}) - + it("prolongs the life of a client", function() { with(this) { clock_tick(450) ping("alice") clock_tick(450) check_client_exists("alice", true) clock_tick(450) check_client_exists("alice", false) }}) }}) - + describe("destroyClient", function() { with(this) { it("removes the given client", function() { with(this) { destroy_client("alice") check_client_exists("alice", false) }}) - + it("publishes an event", function() { with(this) { expect_event("alice", "disconnect", []) destroy_client("alice") }}) describe("when the client has subscriptions", function() { with(this) { before(function() { with(this) { this.message = {"channel": "/messages/foo", "data": "ok"} subscribe("alice", "/messages/foo") }}) - + it("stops the client receiving messages", function() { with(this) { connect("alice", engine) destroy_client("alice") publish(message) expect_no_message("alice") }}) - + it("publishes an event", function() { with(this) { expect_event("alice", "disconnect", []) destroy_client("alice") }}) }}) }}) - + describe("subscribe", function() { with(this) { it("publishes an event", function() { with(this) { expect_event("alice", "subscribe", ["/messages/foo"]) subscribe("alice", "/messages/foo") }}) - + describe("when the client is subscribed to the channel", function() { with(this) { before(function() { this.subscribe("alice", "/messages/foo") }) - + it("does not publish an event", function() { with(this) { expect_no_event("alice", "subscribe", ["/messages/foo"]) subscribe("alice", "/messages/foo") }}) }}) }}) - - + + describe("unsubscribe", function() { with(this) { before(function() { this.subscribe("alice", "/messages/bar") }) - + it("does not publish an event", function() { with(this) { expect_no_event("alice", "unsubscribe", ["/messages/foo"]) unsubscribe("alice", "/messages/foo") }}) - + describe("when the client is subscribed to the channel", function() { with(this) { before(function() { this.subscribe("alice", "/messages/foo") }) - + it("publishes an event", function() { with(this) { expect_event("alice", "unsubscribe", ["/messages/foo"]) unsubscribe("alice", "/messages/foo") }}) }}) }}) - + describe("publish", function() { with(this) { before(function() { with(this) { this.message = {"channel": "/messages/foo", "data": "ok", "blank": null} connect("alice", engine) connect("bob", engine) connect("carol", engine) }}) - + describe("with no subscriptions", function() { with(this) { it("delivers no messages", function() { with(this) { publish(message) expect_no_message("alice") expect_no_message("bob") expect_no_message("carol") }}) - + it("publishes a :publish event with a clientId", function() { with(this) { expect_event("bob", "publish", ["/messages/foo", "ok"]) publish_by("bob", message) }}) - + it("publishes a :publish event with no clientId", function() { with(this) { expect_event(null, "publish", ["/messages/foo", "ok"]) publish(message) }}) }}) - + describe("with a subscriber", function() { with(this) { before(function() { with(this) { subscribe("alice", "/messages/foo") }}) - + it("delivers multibyte messages correctly", function() { with(this) { message.data = "Apple = " publish(message) expect_message("alice", [message]) }}) - + it("delivers messages to the subscribed client", function() { with(this) { publish(message) expect_message("alice", [message]) }}) - + it("publishes a :publish event with a clientId", function() { with(this) { expect_event("bob", "publish", ["/messages/foo", "ok"]) publish_by("bob", message) }}) }}) - + describe("with a subscriber that is removed", function() { with(this) { before(function() { with(this) { subscribe("alice", "/messages/foo") unsubscribe("alice", "/messages/foo") }}) - + it("does not deliver messages to unsubscribed clients", function() { with(this) { publish(message) expect_no_message("alice") expect_no_message("bob") expect_no_message("carol") }}) - + it("publishes a :publish event with a clientId", function() { with(this) { expect_event("bob", "publish", ["/messages/foo", "ok"]) publish_by("bob", message) }}) }}) - + describe("with multiple subscribers", function() { with(this) { before(function() { with(this) { subscribe("alice", "/messages/foo") subscribe("bob", "/messages/bar") subscribe("carol", "/messages/foo") }}) - + it("delivers messages to the subscribed clients", function() { with(this) { publish(message) expect_message("alice", [message]) expect_no_message("bob") expect_message("carol", [message]) }}) }}) - + describe("with a single wildcard", function() { with(this) { before(function() { with(this) { subscribe("alice", "/messages/*") subscribe("bob", "/messages/bar") subscribe("carol", "/*") }}) - + it("delivers messages to matching subscriptions", function() { with(this) { publish(message) expect_message("alice", [message]) expect_no_message("bob") expect_no_message("carol") }}) }}) - + describe("with a double wildcard", function() { with(this) { before(function() { with(this) { subscribe("alice", "/messages/**") subscribe("bob", "/messages/bar") subscribe("carol", "/**") }}) - + it("delivers messages to matching subscriptions", function() { with(this) { publish(message) expect_message("alice", [message]) expect_no_message("bob") expect_message("carol", [message]) }}) - + it("delivers a unique copy of the message to each client", function() { with(this) { publish(message) check_different_messages("alice", "carol") }}) }}) - + describe("with multiple matching subscriptions for the same client", function() { with(this) { before(function() { with(this) { subscribe("alice", "/messages/*") subscribe("alice", "/messages/foo") }}) - + it("delivers each message once to each client", function() { with(this) { publish(message) expect_message("alice", [message]) }}) - + it("delivers the message as many times as it is published", function() { with(this) { publish([message, message]) expect_message("alice", [message, message]) }}) }}) }}) }}) - + sharedBehavior("distributed engine", function() { with(this) { include(JS.Test.Helpers) include(EngineSteps) - + define("create_engine", function() { with(this) { var opts = Faye.extend(options(), engineOpts) return new Faye.Engine.Proxy(opts) }}) - + define("options", function() { return {timeout: 1} }) - + before(function() { with(this) { this.left = create_engine() this.right = create_engine() this.engine = left - + create_client("alice") create_client("bob") - + connect("alice", left) }}) - + describe("publish", function() { with(this) { before(function() { with(this) { subscribe("alice", "/foo") publish({channel: "/foo", data: "first"}) }}) - + it("only delivers each message once", function() { with(this) { expect_message("alice", [{channel: "/foo", data: "first"}]) publish({channel: "/foo", data: "second"}) connect("alice", right) expect_message("alice", [{channel: "/foo", data: "first"}, {channel: "/foo", data: "second"}])