From f1b982feddc65c6891eeeeeadafdb0537da4447e Mon Sep 17 00:00:00 2001 From: Andrew Stewart Date: Mon, 10 Nov 2014 10:52:55 -0800 Subject: [PATCH] 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. --- lib/robot.js | 95 +++++++++++++++++++++++++++++------------- spec/lib/robot.spec.js | 66 +++++++++++++++-------------- 2 files changed, 100 insertions(+), 61 deletions(-) diff --git a/lib/robot.js b/lib/robot.js index 4eb9752..a527847 100644 --- a/lib/robot.js +++ b/lib/robot.js @@ -78,8 +78,8 @@ var Robot = module.exports = function Robot(opts) { this.work = function() { Logger.debug("No work yet."); }; } - this.initConnections(opts.connection || opts.connections); - this.initDevices(opts.device || opts.devices); + this.initConnections(opts); + this.initDevices(opts); for (var n in opts) { var opt = opts[n]; @@ -156,19 +156,15 @@ Robot.prototype.toJSON = function() { // Public: Initializes all connections for the robot // -// connections - connections to initialize +// opts - options array passed to constructor // // Returns initialized connections -Robot.prototype.initConnections = function(connections) { +Robot.prototype.initConnections = function(opts) { Logger.info("Initializing connections."); - if (connections == null) { - return; - } + var isArray = Array.isArray; - connections = [].concat(connections); - - connections.forEach(function(conn) { + var addConnection = function(conn) { conn.robot = this; 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.info("Initializing connection '" + conn.name + "'."); - 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; }; // Public: Initializes all devices for the robot // -// devices - devices to initialize +// opts - options array passed to constructor // // Returns initialized devices -Robot.prototype.initDevices = function(devices) { +Robot.prototype.initDevices = function(opts) { Logger.info("Initializing devices."); - if (devices == null) { - return; - } + var isArray = Array.isArray; - // check that there are connections to use - if (!Object.keys(this.connections).length) { - throw new Error("No connections specified") - } - - devices = [].concat(devices); - - devices.forEach(function(device) { + var addDevice = function(device) { device.robot = this; 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); - }.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; }; diff --git a/spec/lib/robot.spec.js b/spec/lib/robot.spec.js index 6057812..24e5814 100644 --- a/spec/lib/robot.spec.js +++ b/spec/lib/robot.spec.js @@ -233,15 +233,16 @@ describe("Robot", function() { }); context("when not passed anything", function() { - it("returns immediately", function() { - expect(bot.initConnections()).to.be.eql(undefined); + it("does not modify the bot's connections", function() { + bot.initConnections({}); + expect(bot.connections).to.be.eql({}); }); }); context("when passed a connection object", function() { it("instantiates a new connection with the provided object", function() { var connection = { name: 'loopback', adaptor: 'loopback' }; - bot.initConnections(connection); + bot.initConnections({ connection: 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() { it("instantiates a new connection with each of the provided objects", function() { var connections = [{ name: 'loopback', adaptor: 'loopback' }] - bot.initConnections(connections); + bot.initConnections({ connections: connections }); expect(bot.connections['loopback']).to.be.instanceOf(Connection); }); - it("avoids name collisions collisions", function() { - bot.initConnections([ - { name: 'loopback', adaptor: 'loopback' }, - { name: 'loopback', adaptor: 'loopback' } - ]); + it("avoids name collisions", function() { + var opts = { + connections: [ + { name: 'loopback', adaptor: 'loopback' }, + { name: 'loopback', adaptor: 'loopback' } + ] + }; + + bot.initConnections(opts); var keys = Object.keys(bot.connections); expect(keys).to.be.eql(["loopback", "loopback-1"]); @@ -275,36 +280,35 @@ describe("Robot", function() { }); context("when not passed anything", function() { - it("returns immediately", function() { - expect(bot.initDevices()).to.be.eql(undefined); + it("does not modify the bot's devices", function() { + bot.initDevices({}); + expect(bot.devices).to.be.eql({}); }); }); - context("when passed a connection object", function() { - afterEach(function() { bot.devices = {}; }); - + context("when passed a devicw object", function() { it("instantiates a new device with the provided object", function() { var device = { name: 'ping', driver: 'ping' }; - bot.initDevices(device); + bot.initDevices({ device: device }); expect(bot.devices['ping']).to.be.instanceOf(Device); }); }); 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() { var devices = [{ name: 'ping', driver: 'ping' }] - bot.initDevices(devices); + bot.initDevices({ devices: devices}); expect(bot.devices['ping']).to.be.instanceOf(Device); }); it("avoids name collisions collisions", function() { - bot.initDevices([ - { name: 'ping', driver: 'ping' }, - { name: 'ping', driver: 'ping' } - ]); + bot.initDevices({ + devices: [ + { name: 'ping', driver: 'ping' }, + { name: 'ping', driver: 'ping' } + ] + }); var keys = Object.keys(bot.devices); expect(keys).to.be.eql(["ping", "ping-1"]); @@ -353,10 +357,10 @@ describe("Robot", function() { beforeEach(function() { bot = new Robot({ - connections: [ - { name: 'alpha', adaptor: 'loopback' }, - { name: 'bravo', adaptor: 'loopback' } - ] + connections: { + alpha: { adaptor: 'loopback' }, + bravo: { adaptor: 'loopback' } + } }); stub(bot.connections.alpha, 'connect').returns(true); @@ -376,11 +380,11 @@ describe("Robot", function() { beforeEach(function() { bot = new Robot({ - connection: [{ name: 'loopback', adaptor: 'loopback' }], - devices: [ - { name: 'alpha', driver: 'ping' }, - { name: 'bravo', driver: 'ping' } - ] + connection: { name: 'loopback', adaptor: 'loopback' }, + devices: { + alpha: { driver: 'ping' }, + bravo: { driver: 'ping' } + } }); stub(bot.devices.alpha, 'start').returns(true);