File:EventUtils.js
/**
* @module Learning
* @namespace springroll.pbskids
* @requires Core
*/
(function()
{
//Import classes
var ValidationError = include('springroll.pbskids.ValidationError'),
EventError = include('springroll.pbskids.EventError'),
EventCatalog = include('springroll.pbskids.EventCatalog');
/**
* Utility class for handling events
* @class EventUtils
* @private
*/
var EventUtils = {};
/**
* Convert an array of input arguments into a data map
* @method argsMap
* @static
* @param {Array} allArgs All the event arguments
* @param {array} inputs The data to validate
* @return {Object} The validated event data object
*/
EventUtils.argsMap = function(allArgs, inputs)
{
var i, arg, args = [],
data = {};
//Ignore the arguments we don't care about
for (i = 0; i < allArgs.length; i++)
{
arg = allArgs[i];
if (EventCatalog.globals.indexOf(arg.name) === -1)
{
args.push(arg);
}
}
if (args.length != inputs.length)
{
throw new EventError("Arguments length doesn't match the API, expected " +
args.length + " but got " + inputs.length);
}
for (i = 0; i < args.length; i++)
{
arg = args[i];
data[arg.name] = inputs.shift();
}
return data;
};
/**
* Validate arguments
* @method validate
* @static
* @param {Array} args The event arguments
* @param {object} inputs The data to validate
* @return {Object} The validated event data object
*/
EventUtils.validate = function(args, inputs)
{
var arg, input, data = {};
for (var i = 0, len = args.length; i < len; i++)
{
arg = args[i];
//We don't care about these arguments
if (EventCatalog.globals.indexOf(arg.name) !== -1)
{
continue;
}
arg = args[i];
input = inputs[arg.name];
if (input === undefined)
{
throw new EventError("No value found for argument '" + arg.name + "'");
}
validateValue(arg.type, input, arg.args || null, arg.name);
data[arg.name] = input;
}
return data;
};
/**
* Do the actual type validation on a specific value
* @method _validate
* @private
* @constructor
* @param {string|Array} type The type of value, if an array a set of valid items
* @param {*} value The value to test against
* @param {array} args The list of properties to validate if a typed object
*/
var validateValue = function(type, value, args, parent)
{
//Check for empty values
if (value === undefined || value === null)
{
throw new ValidationError("Supplied value is empty", parent, value);
}
//wildcard don't validate
if (type === "*") return;
//validate vanilla strings, ints and numbers
if ((type === "string" && typeof value !== type) ||
(type === "int" && parseInt(value) !== value) ||
(type === "number" && parseFloat(value) !== value) ||
(type === "array" && !Array.isArray(value)) ||
(type === "boolean" && typeof value !== type) ||
(type === "object" && typeof value !== type))
{
throw new ValidationError("Not a valid " + type, parent, value);
}
var i, len;
//Can check for typed arrays, such as an array
//filled with only ints, strings or numbers
if (/^array\-\>(int|boolean|string|number|array|object)$/.test(type))
{
if (!Array.isArray(value))
{
throw new ValidationError(
"Not a valid " + type,
parent,
value
);
}
//Validate each argument on the array
var arrayType = type.replace("array->", "");
for (i = 0, len = value.length; i < len; i++)
{
try
{
validateValue(arrayType, value[i], args, parent);
}
catch (e)
{
throw new ValidationError(
"Invalid " + type + " at index " + i,
parent,
value
);
}
}
}
//Validate set items
if (Array.isArray(type) && type.indexOf(value) === -1)
{
throw new ValidationError(
"Value is not valid in set",
parent,
value
);
}
//Validate properties of an object
if (type === "object" && !!args)
{
len = args.length;
for (i = 0; i < len; i++)
{
var prop = args[i];
validateValue(
prop.type,
value[prop.name],
prop.args,
parent + "." + prop.name
);
}
}
};
//Assign to namespace
namespace('springroll.pbskids').EventUtils = EventUtils;
}());