diff --git a/package.json b/package.json index 13aae98..c0837e0 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "protocol" ], "dependencies": { + "amdefine": "~1", "underscore": "1.5.2" }, "devDependencies": { diff --git a/src/i.js b/src/i.js index f82a364..6c9d36a 100644 --- a/src/i.js +++ b/src/i.js @@ -1,123 +1,127 @@ 'use strict'; -var _ = require('underscore'); +if (typeof define !== 'function') { + var define = require('amdefine')(module); +} -function noOp() {} +define(['underscore'], function (_) { + function noOp() {} -function addFunctionNameToObject(functionName, object) { - if (functionName && _.isString(functionName)) { - object[functionName] = 'function'; + function addFunctionNameToObject(functionName, object) { + if (functionName && _.isString(functionName)) { + object[functionName] = 'function'; + } } -} -function processBlock(block, blockName, outObject) { - if (_.isArray(block[blockName])) { - outObject[blockName] = outObject[blockName] || {}; - _.each(block[blockName], function (value) { - addFunctionNameToObject(value, outObject[blockName]); - }); - } else if (_.isObject(block[blockName])) { - outObject[blockName] = outObject[blockName] || {}; - _.each(block[blockName], function (value, key) { - addFunctionNameToObject(key, outObject[blockName]); - }); + function processBlock(block, blockName, outObject) { + if (_.isArray(block[blockName])) { + outObject[blockName] = outObject[blockName] || {}; + _.each(block[blockName], function (value) { + addFunctionNameToObject(value, outObject[blockName]); + }); + } else if (_.isObject(block[blockName])) { + outObject[blockName] = outObject[blockName] || {}; + _.each(block[blockName], function (value, key) { + addFunctionNameToObject(key, outObject[blockName]); + }); + } } -} -function buildInterface(interfaceDescription) { - var result = { - required: {} - }; + function buildInterface(interfaceDescription) { + var result = { + required: {} + }; + + if (_.isArray(interfaceDescription)) { + _.each(interfaceDescription, function (methodName) { + addFunctionNameToObject(methodName, result.required); + }); + } else if (_.isObject(interfaceDescription)) { + processBlock(interfaceDescription, 'required', result); + processBlock(interfaceDescription, 'optional', result); + } - if (_.isArray(interfaceDescription)) { - _.each(interfaceDescription, function (methodName) { - addFunctionNameToObject(methodName, result.required); - }); - } else if (_.isObject(interfaceDescription)) { - processBlock(interfaceDescription, 'required', result); - processBlock(interfaceDescription, 'optional', result); + return result; } - return result; -} + var Methodical = function (interfaceDescription) { + this._interface = buildInterface(interfaceDescription); + }; -var Methodical = function (interfaceDescription) { - this._interface = buildInterface(interfaceDescription); -}; + Methodical.function = 'function'; -Methodical.function = 'function'; + Methodical.fromConstructor = function (Constructor) { + var requiredMethods; -Methodical.fromConstructor = function (Constructor) { - var requiredMethods; + if (_.isFunction(Constructor)) { + requiredMethods = []; + _.each(Constructor.prototype, function (value, key) { + if (_.isFunction(value)) { + requiredMethods.push(key); + } + }); + } else { + throw new TypeError('A function must be passed'); + } - if (_.isFunction(Constructor)) { - requiredMethods = []; - _.each(Constructor.prototype, function (value, key) { - if (_.isFunction(value)) { - requiredMethods.push(key); - } - }); - } else { - throw new TypeError('A function must be passed'); - } + return new Methodical(requiredMethods); + }; - return new Methodical(requiredMethods); -}; + Methodical.prototype.getInterface = function () { + return this._interface; + }; -Methodical.prototype.getInterface = function () { - return this._interface; -}; + Methodical.prototype.check = function (object) { + var errors = []; -Methodical.prototype.check = function (object) { - var errors = []; + // ensures that if we pass garbage in, we get sensible error messages + if (!_.isObject(object)) { + object = {}; + } - // ensures that if we pass garbage in, we get sensible error messages - if (!_.isObject(object)) { - object = {}; - } + _.each(this.getInterface().required, _.bind(function (value, key) { + if (typeof object[key] !== value) { + errors.push('The required method "' + key + '" is not implemented'); + } + }, this)); - _.each(this.getInterface().required, _.bind(function (value, key) { - if (typeof object[key] !== value) { - errors.push('The required method "' + key + '" is not implemented'); + if (errors.length) { + var throwable = new TypeError(); + var messageIntro = 'The object does not conform to the interface: '; + if (this.name) { + messageIntro = 'The object does not conform to the "' + this.name + '" interface: '; + } + throwable.message = messageIntro + errors.join('; '); + throw throwable; } - }, this)); - if (errors.length) { - var throwable = new TypeError(); - var messageIntro = 'The object does not conform to the interface: '; - if (this.name) { - messageIntro = 'The object does not conform to the "' + this.name + '" interface: '; - } - throwable.message = messageIntro + errors.join('; '); - throw throwable; - } + }; + + Methodical.prototype.complete = function (object) { -}; + if (!_.isFunction(object) && !_.isObject(object)) { + throw new TypeError('Cannot complete a non-object'); + } -Methodical.prototype.complete = function (object) { + _.each(this.getInterface().required, _.bind(function (value, key) { + if (typeof object[key] !== value) { + object[key] = noOp; + } + }, this)); + }; - if (!_.isFunction(object) && !_.isObject(object)) { - throw new TypeError('Cannot complete a non-object'); - } + Methodical.prototype.tryCall = function (object, method) { + var methodArguments = Array.prototype.slice.call(arguments, 2); + this.tryApply(object, method, methodArguments); + }; - _.each(this.getInterface().required, _.bind(function (value, key) { - if (typeof object[key] !== value) { - object[key] = noOp; + Methodical.prototype.tryApply = function (object, method, args) { + if (_.isFunction(object[method])) { + object[method].apply(object, args); + } else if (this.getInterface().required[method] === 'function') { + object[method].apply(object, args); } - }, this)); -}; - -Methodical.prototype.tryCall = function (object, method) { - var methodArguments = Array.prototype.slice.call(arguments, 2); - this.tryApply(object, method, methodArguments); -}; - -Methodical.prototype.tryApply = function (object, method, args) { - if (_.isFunction(object[method])) { - object[method].apply(object, args); - } else if (this.getInterface().required[method] === 'function') { - object[method].apply(object, args); - } -}; + }; -module.exports = Methodical; \ No newline at end of file + return Methodical; +});