Support providing connections/devices as an object

Before:

  connections: [
    { name: 'loopback', adaptor: 'loopback', port: 13 }
  ],

Now:

  connections: {
    loopback: { adaptor: 'loopback', port: 13 }
  }

Array syntax still works, but has been marked as deprecated.
This commit is contained in:
Andrew Stewart 2014-11-10 10:52:55 -08:00
parent efe3d8fef1
commit f1b982fedd
2 changed files with 100 additions and 61 deletions

View File

@ -78,8 +78,8 @@ var Robot = module.exports = function Robot(opts) {
this.work = function() { Logger.debug("No work yet."); }; this.work = function() { Logger.debug("No work yet."); };
} }
this.initConnections(opts.connection || opts.connections); this.initConnections(opts);
this.initDevices(opts.device || opts.devices); this.initDevices(opts);
for (var n in opts) { for (var n in opts) {
var opt = opts[n]; var opt = opts[n];
@ -156,19 +156,15 @@ Robot.prototype.toJSON = function() {
// Public: Initializes all connections for the robot // Public: Initializes all connections for the robot
// //
// connections - connections to initialize // opts - options array passed to constructor
// //
// Returns initialized connections // Returns initialized connections
Robot.prototype.initConnections = function(connections) { Robot.prototype.initConnections = function(opts) {
Logger.info("Initializing connections."); Logger.info("Initializing connections.");
if (connections == null) { var isArray = Array.isArray;
return;
}
connections = [].concat(connections); var addConnection = function(conn) {
connections.forEach(function(conn) {
conn.robot = this; conn.robot = this;
if (this.connections[conn.name]) { if (this.connections[conn.name]) {
@ -177,34 +173,47 @@ Robot.prototype.initConnections = function(connections) {
Logger.warn("Connection names must be unique. Renaming '" + original + "' to '" + conn.name + "'"); Logger.warn("Connection names must be unique. Renaming '" + original + "' to '" + conn.name + "'");
} }
Logger.info("Initializing connection '" + conn.name + "'.");
this.connections[conn.name] = new Connection(conn); this.connections[conn.name] = new Connection(conn);
}.bind(this)); }.bind(this);
if (opts.connection == null && opts.connections == null) {
return this.connections;
}
if (opts.connection) {
addConnection(opts.connection);
return this.connections;
}
if (typeof opts.connections == 'object' && !isArray(opts.connections)) {
for (var name in opts.connections) {
var conn = opts.connections[name];
conn.name = name;
addConnection(conn);
}
}
if (isArray(opts.connections)) {
Logger.warn("Specifying connections as an array is deprecated, and will be removed in 1.0.0.");
opts.connections.forEach(function(conn) {
addConnection(conn);
});
}
return this.connections; return this.connections;
}; };
// Public: Initializes all devices for the robot // Public: Initializes all devices for the robot
// //
// devices - devices to initialize // opts - options array passed to constructor
// //
// Returns initialized devices // Returns initialized devices
Robot.prototype.initDevices = function(devices) { Robot.prototype.initDevices = function(opts) {
Logger.info("Initializing devices."); Logger.info("Initializing devices.");
if (devices == null) { var isArray = Array.isArray;
return;
}
// check that there are connections to use var addDevice = function(device) {
if (!Object.keys(this.connections).length) {
throw new Error("No connections specified")
}
devices = [].concat(devices);
devices.forEach(function(device) {
device.robot = this; device.robot = this;
if (this.devices[device.name]) { if (this.devices[device.name]) {
@ -228,11 +237,37 @@ Robot.prototype.initDevices = function(devices) {
} }
} }
device.adaptor = device.connection.adaptor;
Logger.info("Initializing device '" + device.name + "'.");
this.devices[device.name] = new Device(device); this.devices[device.name] = new Device(device);
}.bind(this)); }.bind(this);
if (opts.device == null && opts.devices == null) {
return this.devices;
}
// check that there are connections to use
if (!Object.keys(this.connections).length) {
throw new Error("No connections specified")
}
if (opts.device) {
addDevice(opts.device);
return this.devices;
}
if (typeof opts.devices == 'object' && !isArray(opts.devices)) {
for (var name in opts.devices) {
var device = opts.devices[name];
device.name = name;
addDevice(device);
}
}
if (isArray(opts.devices)) {
Logger.warn("Specifying devices as an array is deprecated, and will be removed in 1.0.0.");
opts.devices.forEach(function(device) {
addDevice(device);
});
}
return this.devices; return this.devices;
}; };

View File

@ -233,15 +233,16 @@ describe("Robot", function() {
}); });
context("when not passed anything", function() { context("when not passed anything", function() {
it("returns immediately", function() { it("does not modify the bot's connections", function() {
expect(bot.initConnections()).to.be.eql(undefined); bot.initConnections({});
expect(bot.connections).to.be.eql({});
}); });
}); });
context("when passed a connection object", function() { context("when passed a connection object", function() {
it("instantiates a new connection with the provided object", function() { it("instantiates a new connection with the provided object", function() {
var connection = { name: 'loopback', adaptor: 'loopback' }; var connection = { name: 'loopback', adaptor: 'loopback' };
bot.initConnections(connection); bot.initConnections({ connection: connection });
expect(bot.connections['loopback']).to.be.instanceOf(Connection); expect(bot.connections['loopback']).to.be.instanceOf(Connection);
}); });
}); });
@ -249,15 +250,19 @@ describe("Robot", function() {
context("when passed an array of connection objects", function() { context("when passed an array of connection objects", function() {
it("instantiates a new connection with each of the provided objects", function() { it("instantiates a new connection with each of the provided objects", function() {
var connections = [{ name: 'loopback', adaptor: 'loopback' }] var connections = [{ name: 'loopback', adaptor: 'loopback' }]
bot.initConnections(connections); bot.initConnections({ connections: connections });
expect(bot.connections['loopback']).to.be.instanceOf(Connection); expect(bot.connections['loopback']).to.be.instanceOf(Connection);
}); });
it("avoids name collisions collisions", function() { it("avoids name collisions", function() {
bot.initConnections([ var opts = {
connections: [
{ name: 'loopback', adaptor: 'loopback' }, { name: 'loopback', adaptor: 'loopback' },
{ name: 'loopback', adaptor: 'loopback' } { name: 'loopback', adaptor: 'loopback' }
]); ]
};
bot.initConnections(opts);
var keys = Object.keys(bot.connections); var keys = Object.keys(bot.connections);
expect(keys).to.be.eql(["loopback", "loopback-1"]); expect(keys).to.be.eql(["loopback", "loopback-1"]);
@ -275,36 +280,35 @@ describe("Robot", function() {
}); });
context("when not passed anything", function() { context("when not passed anything", function() {
it("returns immediately", function() { it("does not modify the bot's devices", function() {
expect(bot.initDevices()).to.be.eql(undefined); bot.initDevices({});
expect(bot.devices).to.be.eql({});
}); });
}); });
context("when passed a connection object", function() { context("when passed a devicw object", function() {
afterEach(function() { bot.devices = {}; });
it("instantiates a new device with the provided object", function() { it("instantiates a new device with the provided object", function() {
var device = { name: 'ping', driver: 'ping' }; var device = { name: 'ping', driver: 'ping' };
bot.initDevices(device); bot.initDevices({ device: device });
expect(bot.devices['ping']).to.be.instanceOf(Device); expect(bot.devices['ping']).to.be.instanceOf(Device);
}); });
}); });
context("when passed an array of device objects", function() { context("when passed an array of device objects", function() {
afterEach(function() { bot.devices = {}; });
it("instantiates a new device with each of the provided objects", function() { it("instantiates a new device with each of the provided objects", function() {
var devices = [{ name: 'ping', driver: 'ping' }] var devices = [{ name: 'ping', driver: 'ping' }]
bot.initDevices(devices); bot.initDevices({ devices: devices});
expect(bot.devices['ping']).to.be.instanceOf(Device); expect(bot.devices['ping']).to.be.instanceOf(Device);
}); });
it("avoids name collisions collisions", function() { it("avoids name collisions collisions", function() {
bot.initDevices([ bot.initDevices({
devices: [
{ name: 'ping', driver: 'ping' }, { name: 'ping', driver: 'ping' },
{ name: 'ping', driver: 'ping' } { name: 'ping', driver: 'ping' }
]); ]
});
var keys = Object.keys(bot.devices); var keys = Object.keys(bot.devices);
expect(keys).to.be.eql(["ping", "ping-1"]); expect(keys).to.be.eql(["ping", "ping-1"]);
@ -353,10 +357,10 @@ describe("Robot", function() {
beforeEach(function() { beforeEach(function() {
bot = new Robot({ bot = new Robot({
connections: [ connections: {
{ name: 'alpha', adaptor: 'loopback' }, alpha: { adaptor: 'loopback' },
{ name: 'bravo', adaptor: 'loopback' } bravo: { adaptor: 'loopback' }
] }
}); });
stub(bot.connections.alpha, 'connect').returns(true); stub(bot.connections.alpha, 'connect').returns(true);
@ -376,11 +380,11 @@ describe("Robot", function() {
beforeEach(function() { beforeEach(function() {
bot = new Robot({ bot = new Robot({
connection: [{ name: 'loopback', adaptor: 'loopback' }], connection: { name: 'loopback', adaptor: 'loopback' },
devices: [ devices: {
{ name: 'alpha', driver: 'ping' }, alpha: { driver: 'ping' },
{ name: 'bravo', driver: 'ping' } bravo: { driver: 'ping' }
] }
}); });
stub(bot.devices.alpha, 'start').returns(true); stub(bot.devices.alpha, 'start').returns(true);