You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

432 lines
10 KiB

"use strict";
var wrap = require("./util").wrap;
var steed = require("steed")();
/**
* This is a shared mocha test for verifying that an
* ascoltatore is behaving like one.
*
* This requires that the test exposes an instance property
* on `this`.
*
* See as an example:
* https://github.com/mcollina/ascoltatori/blob/master/test/redis_ascoltatore_spec.js
*
* @api public
*/
module.exports = function() {
var expect;
// you MUST depend on chai only if you plan to run
// this test
expect = require("chai").expect;
it("should have a subscribe function", function() {
var that = this;
expect(that.instance).to.respondTo("subscribe");
});
it("should have an publish function", function() {
var that = this;
expect(that.instance).to.respondTo("publish");
});
it("should support a publish/subscribe pattern", function(done) {
var that = this;
that.instance.subscribe("hello", wrap(done), function() {
that.instance.publish("hello");
});
});
it("should support 'pub/sub' combination for pub/sub", function(done) {
var that = this;
that.instance.sub("hello", wrap(done), function() {
that.instance.pub("hello");
});
});
it("should not raise an exception if pub is called without a done callback", function(done) {
this.instance.pub("hello");
setTimeout(done, 50);
});
it("should not raise an exception if sub is called without a done callback", function(done) {
var that = this;
that.instance.sub("hello", function() {});
setTimeout(function() {
// still, some Ascoltatore are async
// and we must give them some time
done();
}, 10);
});
it("should accept a done callback in pub", function(done) {
this.instance.pub("hello", "world", done);
});
it("should support multi-level wildcard at end of topic", function(done) {
var that = this;
that.instance.sub("hello/*", wrap(done), function() {
that.instance.pub("hello/there/42");
});
});
it("should support multi-level wildcard at the end of a topic with no separator", function(done) {
var that = this;
that.instance.sub("hello/*", wrap(done), function() {
that.instance.pub("hello");
});
});
it("should support single-level wildcard at start of topic", function(done) {
var that = this;
that.instance.sub("+/hello", wrap(done), function() {
that.instance.pub("42/hello");
});
});
it("should support single-level wildcard in middle of topic", function(done) {
var that = this;
that.instance.sub("hello/+/end", wrap(done), function() {
that.instance.pub("hello/42/end");
});
});
it("should support single-level wildcard at end of topic", function(done) {
var that = this;
that.instance.sub("hello/+", wrap(done), function() {
that.instance.pub("hello/42");
});
});
it("should support both wildcards in topic", function(done) {
var that = this;
that.instance.sub("hello/+/there/*", wrap(done), function() {
that.instance.pub("hello/foo/there/bar/42/end");
});
});
it("should not match multiple levels with single wildcard", function(done) {
var that = this,
callback = null;
callback = function(topic) {
expect(topic).to.equal(["hello", "42", "there"].join(that.separator));
done();
};
that.instance.sub("hello/+/there", callback, function () {
that.instance.pub("hello/42/43/there");
that.instance.pub("hello/42/there");
});
});
it("should unsubscribe from wildcard topics independently", function(done) {
var that = this,
callback1 = null,
callback2 = null;
callback1 = function(topic) {
expect(topic).to.equal(["hello", "42", "there"].join(that.separator));
done();
};
callback2 = function () { };
that.instance.sub("hello/*/there", callback2, function () {
that.instance.sub("hello/+/there", callback1, function () {
that.instance.unsub("hello/*/there", callback2, function () {
that.instance.pub("hello/42/there");
});
});
});
});
it("should call each matching callback", function(done) {
var that = this,
callback = null,
count = 0;
callback = function(topic) {
expect(topic).to.equal(["hello", "42"].join(that.separator));
count += 1;
if (count === 2) {
done();
}
};
that.instance.sub("hello/42", callback, function () {
that.instance.sub("hello/*", callback, function () {
that.instance.pub("hello/42");
});
});
});
it("should publish the topic name", function(done) {
var that = this;
that.instance.sub("hello/*", function(topic) {
expect(topic).to.equal(["hello", "42"].join(that.separator));
done();
}, function() {
that.instance.pub("hello/42");
});
});
it("should publish the passed argument", function(done) {
var that = this;
that.instance.sub("hello/*", function(topic, value) {
expect(value.toString()).to.equal("42");
done();
}, function() {
that.instance.pub("hello/123", "42");
});
});
it("should have an unsubscribe function", function() {
var that = this;
expect(that.instance).to.respondTo("unsubscribe");
});
it("should have an unsub function", function() {
var that = this;
expect(that.instance).to.respondTo("unsub");
});
it("should remove a listener", function(done) {
var that = this;
var funcToRemove = null;
funcToRemove = function(topic, value) {
throw "that should never run";
};
steed.series([
function(cb) {
that.instance.sub("hello", funcToRemove, cb);
},
function(cb) {
that.instance.sub("hello", wrap(done), cb);
},
function(cb) {
that.instance.unsub("hello", funcToRemove, cb);
},
function(cb) {
that.instance.pub("hello", null, cb);
}
]);
});
it("should remove a listener for global searches", function(done) {
var that = this,
funcToRemove = null;
funcToRemove = function(topic, value) {
throw "that should never run";
};
steed.series([
function(cb) {
that.instance.sub("hello/42", wrap(done), cb);
},
function(cb) {
that.instance.sub("hello/*", funcToRemove, cb);
},
function(cb) {
that.instance.unsub("hello/*", funcToRemove, cb);
},
function(cb) {
that.instance.pub("hello/42", null, cb);
}
]);
});
it("support at least 10 listeners", function(done) {
var instance = this.instance,
counter = 11,
i = null,
callback = null,
subscribe = null,
a = [];
callback = function() {
counter = counter - 1;
if (counter === 0) {
done();
}
};
subscribe = function (done) {
instance.subscribe("hello", callback, done);
};
for (i = counter; i > 0; i = i - 1) {
a.push(subscribe);
}
steed.parallel(a, instance.publish.bind(instance, "hello", null));
});
it("should emit the ready event", function(done) {
this.instance.on("ready", done);
});
it("should support at least 12 listeners as an EventEmitter", function(done) {
var counter = 11,
i = null,
callback, a = [];
callback = function() {
counter = counter - 1;
if (counter === 0) {
done();
}
};
for (i = counter; i > 0; i = i - 1) {
a.push(this.instance.on.bind(this.instance, "ready", callback));
}
steed.parallel(a);
});
it("should support removing a single listener", function(done) {
var that = this,
funcToRemove;
funcToRemove = function(topic, value) {
throw "that should never run";
};
steed.series([
function(cb) {
that.instance.sub("hello", wrap(done), cb);
},
function(cb) {
that.instance.sub("hello", funcToRemove, cb);
},
function(cb) {
that.instance.unsub("hello", funcToRemove, cb);
},
function(cb) {
that.instance.pub("hello", null, cb);
}
]);
});
it("should have a close function", function() {
var that = this;
expect(that.instance).to.respondTo("close");
});
it("should throw an error if publishing when the ascoltatore has been closed", function(done) {
this.instance.close(function() {
expect(function() {
this.instance.publish("hello", "world");
}).to.throw;
done();
});
});
it("should throw an error if subscribing when the ascoltatore has been closed", function(done) {
this.instance.close(function() {
expect(function() {
this.instance.subscribe("hello");
}).to.throw;
done();
});
});
it("should close using a callback", function(done) {
var that = this;
this.instance.publish("hello", "world", function() {
that.instance.close(done);
});
});
it("should allow the close method to be called twice", function(done) {
var that = this;
steed.series([
this.instance.publish.bind(this.instance, "hello", "world"),
this.instance.close.bind(this.instance),
this.instance.close.bind(this.instance)
], done);
});
it("should not deliver message twice for double subscription", function(done) {
var that = this,
count = 2,
sub = null,
d = null;
d = function() {
count = count - 1;
if (count === 0) {
done();
}
};
sub = function(cb) {
var called = false;
that.instance.sub("hello", function() {
expect(called).to.be.equal(false);
called = true;
d();
}, cb);
};
steed.series([
sub, sub,
function(cb) {
that.instance.pub("hello", "ahha", cb);
}
]);
});
it("should not deliver message twice for multiple subscriptions using wildcards", function(done) {
var that = this,
count = 3,
sub = null,
d = null;
d = function() {
count = count - 1;
if (count === 0) {
done();
}
};
sub = function(topic, cb) {
var called = false;
that.instance.sub(topic, function() {
expect(called).to.equal(false);
called = true;
d();
}, cb);
};
steed.series([
function (cb) {
sub("a/+", cb);
},
function (cb) {
sub("+/b", cb);
},
function (cb) {
sub("a/b", cb);
},
function(cb) {
that.instance.pub("a/b", "ahha", cb);
}
]);
});
};