diff --git a/lib/robot.js b/lib/robot.js index 28a08c2..222ec2b 100644 --- a/lib/robot.js +++ b/lib/robot.js @@ -14,6 +14,8 @@ var initializer = require("./initializer"), Config = require("./config"), _ = require("./utils/helpers"); +var validator = require("./validator"); + var Async = require("async"), EventEmitter = require("events").EventEmitter; @@ -36,6 +38,8 @@ var Robot = module.exports = function Robot(opts) { opts = opts || {}; + validator.validate(opts); + var methods = [ "toString", "halt", @@ -53,9 +57,6 @@ var Robot = module.exports = function Robot(opts) { }, this); this.initRobot(opts); - - this.checkForBadSyntax(opts); - this.initConnections(opts); this.initDevices(opts); @@ -166,37 +167,6 @@ Robot.prototype.initRobot = function(opts) { } }; -/** - * Checks provided options object for invalid Robot details - * - * @param {Object} opts options object to check for errors - * @return {void} - */ -Robot.prototype.checkForBadSyntax = function(opts) { - var self = this; - - var RobotDSLError = new Error("Unable to start robot due to a syntax error"); - RobotDSLError.name = "RobotDSLError"; - - function has(prop) { return opts[prop] != null; } - - function checkForSingleObjectSyntax(type) { - var plural = type + "s"; - - if (has(type) && !has(plural)) { - [ - "The single-object '" + type + "' syntax for robots is not valid.", - "Instead, use the multiple-value '" + plural + "' key syntax.", - "Details: http://cylonjs.com/documentation/guides/working-with-robots/" - ].forEach(function(str) { self.log("fatal", str); }); - - throw RobotDSLError; - } - } - - ["connection", "device"].forEach(checkForSingleObjectSyntax); -}; - /** * Initializes a Robot's connections * diff --git a/lib/validator.js b/lib/validator.js new file mode 100644 index 0000000..06f60d7 --- /dev/null +++ b/lib/validator.js @@ -0,0 +1,93 @@ +"use strict"; + +// validates an Object containing Robot parameters + +var Logger = require("./logger"), + _ = require("./utils/helpers"); + +function hasProp(object, prop) { + return object.hasOwnProperty(prop); +} + +function die() { + var RobotDSLError = new Error("Unable to start robot due to a syntax error"); + RobotDSLError.name = "RobotDSLError"; + throw RobotDSLError; +} + +function warn(messages) { + messages = [].concat(messages); + messages.map(function(msg) { Logger.warn(msg); }); +} + +function fatal(messages) { + messages = [].concat(messages); + messages.map(function(msg) { Logger.fatal(msg); }); + die(); +} + +var checks = {}; + +checks.singleObjectSyntax = function(opts, key) { + var single = hasProp(opts, key), + plural = hasProp(opts, key + "s"); + + if (single && !plural) { + fatal([ + "The single-object '" + key + "' syntax for robots is not valid.", + "Instead, use the multiple-value '" + key + "s' key syntax.", + "Details: http://cylonjs.com/documentation/guides/working-with-robots/" + ]); + } +}; + +checks.singleObjectSyntax = function(opts) { + ["connection", "device"].map(function(key) { + var single = hasProp(opts, key), + plural = hasProp(opts, key + "s"); + + if (single && !plural) { + fatal([ + "The single-object '" + key + "' syntax for robots is not valid.", + "Instead, use the multiple-value '" + key + "s' key syntax.", + "Details: http://cylonjs.com/documentation/guides/working-with-robots/" + ]); + } + }); +}; + +checks.deviceWithoutDriver = function(opts) { + if (opts.devices) { + _.each(opts.devices, function(device, name) { + if (!device.driver || device.driver === "") { + fatal("No driver supplied for device " + name); + } + }); + } +}; + +checks.devicesWithoutConnection = function(opts) { + var connections = opts.connections, + devices = opts.devices; + + if (devices && connections && Object.keys(connections).length > 1) { + var first = Object.keys(connections)[0]; + + _.each(devices, function(device, name) { + if (!device.connection || device.connection === "") { + warn([ + "No explicit connection provided for device " + name, + "Will default to using connection " + first + ]); + } + }); + } +}; + +module.exports.validate = function validate(opts) { + opts = opts || {}; + + _.each(checks, function(check) { + check(opts); + }); +};