Socket
Socket
Sign inDemoInstall

joi

Package Overview
Dependencies
2
Maintainers
2
Versions
238
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.0.5 to 0.0.6

lib/index.js

2

index.js

@@ -1,1 +0,1 @@

module.exports = require('./lib/joi');
module.exports = require('./lib');

@@ -1,19 +0,36 @@

var sys = require("sys");
var util = require('util');
// Load modules
var Sys = require('sys');
var NodeUtil = require('util');
var BaseType = require('./base');
var Utils = require("../utils");
var Utils = require('../utils');
function ArrayType() {
ArrayType.super_.call(this);
// Declare internals
var internals = {};
module.exports = internals.createType = function () {
return new internals.ArrayType();
};
module.exports.ArrayType = internals.ArrayType = function () {
internals.ArrayType.super_.call(this);
Utils.mixin(this, BaseType);
}
util.inherits(ArrayType, BaseType);
return this;
};
ArrayType.prototype.__name = 'Array';
NodeUtil.inherits(internals.ArrayType, BaseType);
ArrayType.prototype.convert = function(value) {
internals.ArrayType.prototype.__name = 'Array';
internals.ArrayType.prototype.convert = function (value) {
if (typeof value === 'string') {

@@ -25,59 +42,58 @@

if (converted instanceof Array) {
return converted;
}
else {
return [converted];
}
}
catch (e){
// console.log(e, value)
catch (e) {
}
}
else {
// Defensive programming
// throw "Invalid data type passed to Types.Array (" + value + ", " + typeof value + " is not supported)";
// throw 'Invalid data type passed to Types.Array (' + value + ', ' + typeof value + ' is not supported)';
return value;
}
}
};
ArrayType.prototype._base = function() {
return function(value, qs, key, errors) {
// console.log('value in Array.base', value)
internals.ArrayType.prototype._base = function () {
return function (value, qs, key, errors) {
return value instanceof Array;
};
}
};
ArrayType.prototype.base = function() {
internals.ArrayType.prototype.base = function () {
this.add('base', this._base(), arguments);
return this;
}
};
ArrayType.prototype.emptyOk = function() {
internals.ArrayType.prototype.emptyOk = function () {
this.allow([]);
this.__modifiers.add("emptyOk");
this.__modifiers.add('emptyOk');
return this;
}
};
ArrayType.prototype._includes = function() {
internals.ArrayType.prototype._includes = function () {
var self = this;
var subElement = (new ArrayType.super_()).getDataKey();
var subElement = (new internals.ArrayType.super_()).getDataKey();
var args = Array.prototype.slice.call(arguments);
var allowedTypes = args.map(function(d) {
var allowedTypes = args.map(function (d) {
return d[subElement];
});
return function(values, qs, key, req) {
req = req || {}
req.add = req.add || function(){}
return function (values, qs, key, req) {
req = req || {};
req.add = req.add || function () { };
// For each allowed Type

@@ -91,4 +107,5 @@ var valueIsValid = true;

var validatedValuesTable = {};
var m = 0;
for(var i = 0; i < allowedTypes.length; i++) {
for (var i = 0; i < allowedTypes.length; i++) {

@@ -99,6 +116,6 @@ // For each validator specified

var validatorIsValid = true;
for(var j = 0; j < validators.length; j++) {
for (var j = 0; j < validators.length; j++) {
// For each input supplied
for(var m = 0; m < values.length; m++) {
for (m = 0; m < values.length; m++) {

@@ -111,3 +128,3 @@ var value = values[m];

// intermediateInvalidValues.push(value);
failedArg = i
failedArg = i;
failedIndex = j;

@@ -117,4 +134,3 @@ failedValue = value;

else {
// console.log(value, "is valid", currentType)
// console.log(value, 'is valid', currentType)
validatedValuesTable[m] = true;

@@ -125,7 +141,5 @@ }

}
for(var m = 0; m < values.length; m++) {
for (m = 0; m < values.length; m++) {
if (!validatedValuesTable.hasOwnProperty(m)) {
invalidValues.push(values[m]);

@@ -135,11 +149,11 @@ valueIsValid = false;

}
// Only append error if the included types' validators return errors
// if (valueIsValid === false && failedIndex >= 0 && args[0].__checks.indexOf("includes") < 0) {
// if (valueIsValid === false && failedIndex >= 0 && args[0].__checks.indexOf('includes') < 0) {
if (valueIsValid === false) {
// if(self.options.debug === true) console.log("***", validatedValuesTable, values)
var validTypes = args.map(function(d){ return d.type; });
var vals = invalidValues.map(function(d){ return JSON.stringify(d)}).join(", ").replace(/[\"]/g, "'")
var msg = "the value(s) `" + vals + "` in array `" + key + "` must be of the following type(s) " + sys.inspect(validTypes);
// if(self.options.debug === true) console.log('***', validatedValuesTable, values)
var validTypes = args.map(function (d) { return d.type; });
var vals = invalidValues.map(function (d) { return JSON.stringify(d) }).join(', ').replace(/[\']/g, '\'')
var msg = 'the value(s) `' + vals + '` in array `' + key + '` must be of the following type(s) ' + Sys.inspect(validTypes);
req.add(msg);

@@ -151,74 +165,114 @@ // console.log(msg)

}
}
};
ArrayType.prototype.includes = function() {
internals.ArrayType.prototype.includes = function () {
this.add('includes', this._includes.apply(this, arguments), arguments);
return this;
}
};
ArrayType.prototype._excludes = function() {
internals.ArrayType.prototype._excludes = function () {
var self = this;
var subElement = (new ArrayType.super_()).getDataKey();
var subElement = (new internals.ArrayType.super_()).getDataKey();
var args = Array.prototype.slice.call(arguments);
var allowedTypes = args.map(function(d) {
var allowedTypes = args.map(function (d) {
return d[subElement];
});
return function(value, qs, key, req) {
return function (value, qs, key, req) {
req = req || {};
req.add = req.add || function(){};
req.add = req.add || function () { };
var typeTable = {
"string": require("./string")(),
"boolean": require("./boolean")(),
"number": require("./number")(),
"array": CreateType(),
// "object": require("./object")()
'string': require('./string')(),
'boolean': require('./boolean')(),
'number': require('./number')(),
'array': internals.createType()
};
var validTypes = args.map(function(d){ return d.type; });
var handler = function(arg) {
var validTypes = args.map(function (d) { return d.type; });
var handler = function (arg) {
delete typeTable[arg.type.toLowerCase()];
var result = self._includes(arg)(value, qs, key, req);
return result;
}
};
var components = args.map(handler);
if (components.indexOf(true) >= 0) {
req.add("the values supplied to array `" + key + "` must contain " + JSON.stringify(validTypes));
req.add('the values supplied to array `' + key + '` must contain ' + JSON.stringify(validTypes));
return false;
}
var difference = Object.keys(typeTable).map(function(d){
var difference = Object.keys(typeTable).map(function (d) {
return typeTable[d];
}).map(handler);
if (difference.indexOf(true) >= 0) {
return true;
}
req.add("the values supplied to array `" + key + "` must contain " + JSON.stringify(validTypes));
req.add('the values supplied to array `' + key + '` must contain ' + JSON.stringify(validTypes));
return false;
}
}
};
};
ArrayType.prototype.excludes = function(){
internals.ArrayType.prototype.excludes = function () {
this.add('excludes', this._excludes.apply(this, arguments), arguments);
return this;
}
};
function CreateType() {
return new ArrayType();
}
/*
internals.StringType.prototype._base = function () {
module.exports = CreateType;
module.exports.ArrayType = ArrayType;
return function (value, qs, key, req) {
return typeof value === 'string';
// Deprecated code below should be moved to Array
// var keyDoesNotExist = !qs.hasOwnProperty(key);
// var valueIsMinLength = (qs[key] !== undefined && qs[key].length >= 1);
// var valueIsNotNumber = isNaN(+value) || isNaN((new Date(+value)).getTime());
// // req = req || {};
// // req.add = req.add || function(){};
// // var valueIsNotArray = !(value instanceof Array);
// var valueIsNotObject = true;
// if (typeof value !== 'string') {
// valueIsNotObject = typeof value !== 'object';
// }
// else {
// try {
// var v = JSON.parse(value);
// valueIsNotObject = (typeof v !== 'object' && !(v instanceof Array))
// }
// catch (e) {
// // console.log(e)
// }
// }
// var valueIsDefined = (keyDoesNotExist || valueIsMinLength);
// if (valueIsDefined === false) {
// req.add('the value of `' + key + '` is not allowed to be the empty string (\'\')');
// }
// var result = (valueIsDefined &&
// valueIsNotNumber &&
// valueIsNotObject);
// return result;
};
};
*/

@@ -1,160 +0,178 @@

/**
* Module dependencies.
*/
// Load modules
var Utils = require('../utils');
var Set = require('../set');
/**
* Constants
*/
var INTERNAL_DATA_KEY = '__validators';
var INTERNAL_KEY_LIST = '__checks';
var INTERNAL_ARGS_LIST = '__args';
/**
* BaseType Constructor
*
* @api public
*/
var BaseType = function() {
this[INTERNAL_DATA_KEY] = [];
this[INTERNAL_KEY_LIST] = [];
this[INTERNAL_ARGS_LIST] = [];
this.__modifiers = new Utils.Set([]);
this.__valids = new Utils.Set(this.__defaultValids || []);
this.__invalids = new Utils.Set(this.__defaultInvalids || []);
// Declare internals
var internals = {
DATA_KEY: '__validators',
KEY_LIST: '__checks',
ARGS_LIST: '__args'
};
module.exports = internals.BaseType = function () {
this[internals.DATA_KEY] = [];
this[internals.KEY_LIST] = [];
this[internals.ARGS_LIST] = [];
this.__modifiers = new Set([]);
this.__valids = new Set(this.__defaultValids || []);
this.__invalids = new Set(this.__defaultInvalids || []);
this.__allowOnly = false;
this.options = {
shortCircuit: true
};
if (typeof this.base !== 'undefined' && this.base !== null) {
if (typeof this.base !== 'undefined' &&
this.base !== null) {
this.base();
}
if (typeof this.__name !== 'undefined' && this.__name !== null) {
if (typeof this.__name !== 'undefined' &&
this.__name !== null) {
this['type'] = this.__name;
}
}
BaseType.prototype.__defaultValids = [undefined];
BaseType.prototype.__defaultInvalids = [null];
return this;
};
BaseType.prototype.mutatorMethods = {
internals.BaseType.prototype.__defaultValids = [undefined];
internals.BaseType.prototype.__defaultInvalids = [null];
internals.BaseType.prototype.mutatorMethods = {
rename: 1
};
BaseType.prototype.valueOf = function() {
// return this[INTERNAL_DATA_KEY];
internals.BaseType.prototype.valueOf = function () {
var value = {
"__valids": this.__valids,
"__invalids": this.__invalids,
"__modifiers": this.__modifiers._values,
"options": this.options
}
value[INTERNAL_DATA_KEY] = this[INTERNAL_DATA_KEY]
value[INTERNAL_KEY_LIST] = this[INTERNAL_KEY_LIST]
value[INTERNAL_ARGS_LIST] = this[INTERNAL_ARGS_LIST]
__valids: this.__valids,
__invalids: this.__invalids,
__modifiers: this.__modifiers._values,
options: this.options
};
value[internals.DATA_KEY] = this[internals.DATA_KEY]
value[internals.KEY_LIST] = this[internals.KEY_LIST]
value[internals.ARGS_LIST] = this[internals.ARGS_LIST]
return value;
}
};
BaseType.prototype.getDataKey = function() {
return INTERNAL_DATA_KEY;
}
BaseType.prototype.toString = function() {
internals.BaseType.prototype.getDataKey = function () {
return internals.DATA_KEY;
};
internals.BaseType.prototype.toString = function () {
return JSON.stringify(this.valueOf());
}
};
BaseType.prototype.add = function(key, value, args) {
if (typeof key == 'undefined' || key == null) {
throw '(type).add must given a key';
}
internals.BaseType.prototype.add = function (key, value, args) {
Utils.assert(typeof key !== 'undefined' && key !== null, '(type).add must be given a key');
if (typeof value !== 'undefined' && value !== null) {
// TODO: add check for invalid keys
this[INTERNAL_DATA_KEY].push(value);
this[INTERNAL_KEY_LIST].push(key)
this[INTERNAL_ARGS_LIST].push(args);
this[internals.DATA_KEY].push(value);
this[internals.KEY_LIST].push(key)
this[internals.ARGS_LIST].push(args);
}
return this[INTERNAL_DATA_KEY];
}
var exists = function(n) {
return this[internals.DATA_KEY];
};
return (typeof n !== 'undefined' &&
n !== null);
}
BaseType.prototype.exists = exists;
BaseType.prototype.allow = function(value) {
internals.BaseType.prototype.exists = function (n) {
return (typeof n !== 'undefined' && n !== null);
};
internals.BaseType.prototype.allow = function (value) {
this.__invalids.remove(value);
this.__valids.add(value);
return this;
}
};
BaseType.prototype.deny = function(value) {
internals.BaseType.prototype.deny = function (value) {
this.__valids.remove(value);
this.__invalids.add(value);
return this;
}
};
BaseType.prototype.required = function() {
internals.BaseType.prototype.required = function () {
this.deny(undefined);
this.__modifiers.add("required");
this.__modifiers.add('required');
return this;
}
};
BaseType.prototype.nullOk = function() {
internals.BaseType.prototype.nullOk = function () {
this.allow(null);
this.__modifiers.add("nullOk");
this.__modifiers.add('nullOk');
return this;
}
};
BaseType.prototype.empty = function(){
internals.BaseType.prototype.empty = function () {
this.allow(null);
this.__modifiers.add("empty");
this.__modifiers.add('empty');
return this;
}
};
BaseType.prototype.valid = function() {
internals.BaseType.prototype.valid = function () {
var acceptable = Array.prototype.slice.call(arguments);
for(var i = acceptable.length - 1; i >= 0; i--) {
Utils.assert(this.validate(acceptable[i]) == true, "input to .valid() must be valid " + this.__name + "(" + acceptable[i] + ")");
for (var i = acceptable.length - 1; i >= 0; --i) {
Utils.assert(this.validate(acceptable[i]) == true, 'input to .valid() must be valid ' + this.__name + '(' + acceptable[i] + ')');
this.allow(acceptable[i]);
}
this.__allowOnly = true;
return this;
}
};
BaseType.prototype.invalid = function() {
internals.BaseType.prototype.invalid = function () {
var unacceptable = Array.prototype.slice.call(arguments);
for(var i = unacceptable.length - 1; i >= 0; i--) {
Utils.assert(this.validate(unacceptable[i]) == true, "input to .invalid() must be valid " + this.__name + "(" + unacceptable[i] + ")");
for (var i = unacceptable.length - 1; i >= 0; --i) {
Utils.assert(this.validate(unacceptable[i]) == true, 'input to .invalid() must be valid ' + this.__name + '(' + unacceptable[i] + ')');
this.deny(unacceptable[i]);
}
return this;
}
};
BaseType.prototype._with = function(peers) {
return function(value, qstr, key) {
internals.BaseType.prototype._with = function (peers) {
// return function(value, qstr) {
return function (value, qstr, key) {
// TODO: make sure keys exists
for(var i in peers) {
for (var i in peers) {
if (!qstr.hasOwnProperty(peers[i]) || peers[i] === null) {
return false;

@@ -164,127 +182,132 @@ }

return true;
}
}
};
};
BaseType.prototype.with = function() {
internals.BaseType.prototype.with = function () {
this.add('with', this._with(Array.prototype.slice.call(arguments)), arguments);
return this;
}
};
BaseType.prototype._without = function(peers) {
internals.BaseType.prototype._without = function (peers) {
var self = this;
return function(value, qstr) {
return function (value, qstr) {
return !self._with(peers)(value, qstr);
}
}
};
BaseType.prototype.without = function() {
internals.BaseType.prototype.without = function () {
this.add('without', this._without(Array.prototype.slice.call(arguments)), arguments);
return this;
}
};
BaseType.prototype._renameDefaultOptions = {
internals.BaseType.prototype._renameDefaultOptions = {
deleteOrig: false,
allowMult: false,
allowOverwrite: false
}
};
BaseType.prototype._rename = function(to, options) {
internals.BaseType.prototype._rename = function (to, options) {
var self = this;
options = Utils.merge(Utils.clone(this._renameDefaultOptions), options);
return function(value, qstr, key, req) {
return function (value, qstr, key, req) {
req = req || {};
req.add = req.add || function(){};
req.add = req.add || function () { };
var renamed = req._renamed || {};
if (options.allowMult === false && to in renamed) {
req.add("allowMult false and already renamed");
req.add('allowMult false and already renamed');
return false;
}
if (options.allowOverwrite === false && qstr.hasOwnProperty(to)) {
// console.log(key, to, qstr)
req.add("allowOverwrite false and target exists: " + key + ", " + to);
req.add('allowOverwrite false and target exists: ' + key + ', ' + to);
return false;
}
qstr[to] = value;
if (options.deleteOrig === true) {
delete qstr[key];
}
if (options.allowMult === false) {
renamed[to] = renamed[to]++ || 1;
}
key = to;
return true;
}
}
};
};
BaseType.prototype.rename = function(to, options) {
internals.BaseType.prototype.rename = function (to, options) {
this.add('rename', this._rename(to, options), arguments);
return this;
}
};
BaseType.prototype.description = function(desc) {
internals.BaseType.prototype.description = function (desc) {
Utils.assert(typeof desc === 'string', 'Validator description must be a string');
this.description = desc || '';
return this;
}
};
BaseType.prototype.notes = function(notes) {
internals.BaseType.prototype.notes = function (notes) {
Utils.assert(typeof notes === 'string' || notes instanceof Array, 'Validator notes must be a string or array');
this.notes = notes || '';
return this;
}
};
BaseType.prototype.tags = function(tags) {
internals.BaseType.prototype.tags = function (tags) {
Utils.assert(tags instanceof Array, 'Validator tags must be an array');
this.tags = tags || [];
return this;
}
};
BaseType.prototype.RequestErrorFactory = function(request) {
internals.BaseType.prototype.RequestErrorFactory = function (request) {
request.validationErrors = [];
return function(msg){
var err = "[ValidationError]: " + msg.toString();
return function (msg) {
var err = '[ValidationError]: ' + msg.toString();
request.validationErrors.push(err);
}
}
};
};
BaseType.prototype.validate = function(value, key, obj, errors) {
internals.BaseType.prototype.validate = function (value, key, obj, errors) {
var status = true;
var finalizeFns = [];
key = key || "0";
obj = obj || {"0": value};
key = key || '0';
obj = obj || { '0': value };
errors = errors || {};
errors.add = errors.add || function(){};
// console.log(this.valueOf())
errors.add = errors.add || function () { };
// Check vs valid/invalid values
if (this.__invalids._values.indexOf(value) >= 0) {
status = false;
errors.add("the value of `" + key + "` is not allowed to be " + this.__invalids._values[this.__invalids._values.indexOf(value)]);
errors.add('the value of `' + key + '` is not allowed to be ' + this.__invalids._values[this.__invalids._values.indexOf(value)]);
if (this.options.shortCircuit === true) {

@@ -294,2 +317,3 @@ return status;

}
if (this.__valids._values.indexOf(value) >= 0) {

@@ -302,17 +326,23 @@ status = true;

if (this.__allowOnly === true &&
this.__valids._values.indexOf(value) < 0) {
status = false;
if (this.options.shortCircuit === true) {
return status;
}
}
// Evaluate validators
for(var j in this.__validators) {
for (var j in this.__validators) {
// TODO: handle finalizeFns aka mutators (need to run after all other validators)
var validatorName = this.__checks[j];
if (validatorName in this.mutatorMethods) {
// console.log("mutatorMethod found", this.__checks[j])
finalizeFns.push(j);
continue;
}
var result = this.__validators[j](value, obj || {"0": value}, key || "0", errors)
// console.log("validating", this.type, this.__checks[j], value, typeof value, result)
var result = this.__validators[j](value, obj || { '0': value }, key || '0', errors);
if (result === false) {
// console.log(this.__checks[j], "failed with ", value)
status = false;

@@ -324,7 +354,6 @@ if (this.options.shortCircuit === true) {

}
for(var l in finalizeFns) {
var result = this.__validators[finalizeFns[l]](value, obj || {"0": value}, key || "0", errors)
for (var l in finalizeFns) {
var result = this.__validators[finalizeFns[l]](value, obj || { '0': value }, key || '0', errors);
if (result === false) {
// console.log("finalize:", this.__checks[l], "failed with ", value)
status = false;

@@ -336,6 +365,4 @@ if (this.options.shortCircuit === true) {

}
return status;
}
module.exports = BaseType;
};

@@ -1,66 +0,63 @@

var util = require("util");
var BaseType = require("./base");
var Utils = require("../utils");
// Load modules
function BooleanType() {
var NodeUtil = require('util');
var BaseType = require('./base');
var Utils = require('../utils');
BooleanType.super_.call(this);
Utils.mixin(this, BaseType);
}
util.inherits(BooleanType, BaseType);
// Declare internals
BooleanType.prototype.__name = "Boolean";
var internals = {};
BooleanType.prototype.convert = function(value) {
if (typeof value == "string") {
module.exports = internals.createType = function () {
switch (value.toLowerCase()) {
return new internals.BooleanType();
};
case "true":
return true;
break;
case "false":
default:
return false;
break;
}
}
else {
module.exports.BooleanType = internals.BooleanType = function () {
internals.BooleanType.super_.call(this);
Utils.mixin(this, BaseType);
return this;
};
NodeUtil.inherits(internals.BooleanType, BaseType);
internals.BooleanType.prototype.__name = 'Boolean';
internals.BooleanType.prototype.convert = function (value) {
if (typeof value !== 'string') {
return value;
}
}
BooleanType.prototype._base = function() {
return value.toLowerCase() === 'true';
};
return function(value, qs, key, req) {
req = req || {}
req.add = req.add || function(){}
internals.BooleanType.prototype._base = function () {
var result = (value == null || typeof value == "boolean");
if (result === false) {
return function (value, qs, key, req) {
req.add("the value of `" + key + "` must be a boolean");
req = req || {};
req.add = req.add || function () { };
var result = (value === null || typeof value === 'boolean');
if (!result) {
req.add('the value of `' + key + '` must be a boolean');
}
return result;
};
}
};
BooleanType.prototype.base = function() {
internals.BooleanType.prototype.base = function () {
this.add('base', this._base(), arguments);
return this;
}
};
function CreateType() {
return new BooleanType();
}
module.exports = CreateType;
module.exports.BooleanType = BooleanType;

@@ -1,11 +0,20 @@

/*
* Email regular expression adapted from node-validator, Copyright (c) 2010-2012 Chris O'Hara <cohara87@gmail.com>
* node-validator is released under the MIT License and is available at https://github.com/chriso/node-validator
*/
// Load modules
var Email = function() {
}
module.exports = new Email();
// Declare internals
Email.prototype._regex = /^(?:[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+\.)*[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+@(?:(?:(?:[a-zA-Z0-9](?:[a-zA-Z0-9\-](?!\.)){0,61}[a-zA-Z0-9]?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9\-](?!$)){0,61}[a-zA-Z0-9]?)|(?:\[(?:(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\.){3}(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\]))$/;
var internals = {};
internals.Email = function () {
};
module.exports = new internals.Email();
// Email regular expression adapted from node-validator, Copyright (c) 2010-2012 Chris O'Hara <cohara87@gmail.com>
// node-validator is released under the MIT License and is available at https://github.com/chriso/node-validator
internals.Email.prototype._regex = /^(?:[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+\.)*[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+@(?:(?:(?:[a-zA-Z0-9](?:[a-zA-Z0-9\-](?!\.)){0,61}[a-zA-Z0-9]?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9\-](?!$)){0,61}[a-zA-Z0-9]?)|(?:\[(?:(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\.){3}(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\]))$/;

@@ -1,18 +0,17 @@

/**
* Module dependencies.
*/
var BaseType = require("./base");
var StringType = require("./string");
var NumberType = require("./number");
var BooleanType = require("./boolean");
var ArrayType = require("./array");
var ObjectType = require("./object");
// Load modules
/**
* Types Constructor
*
* @api public
*/
function Types(){
var BaseType = require('./base');
var StringType = require('./string');
var NumberType = require('./number');
var BooleanType = require('./boolean');
var ArrayType = require('./array');
// Declare internals
var internals = {};
internals.Types = function () {
// Load types

@@ -25,18 +24,20 @@

this.Array = ArrayType;
// this.Object = ObjectType;
}
Types.prototype.mutatorMethods = {
return this;
};
module.exports = new internals.Types();
internals.Types.prototype.mutatorMethods = {
rename: 1
}
};
Types.prototype.validate = function(key, type, object, validator, placeholder) {
try {
var value = object[key];
} catch (e) {
throw e;
}
internals.Types.prototype.validate = function (key, type, object, validator, placeholder) {
var value = object[key];
// Convert value from String if necessary

@@ -51,23 +52,19 @@

}
// Set request-scoped error writer
// errors stored as placeholder.validationErrors = []
if (placeholder) {
placeholder.add = this.Base.prototype.RequestErrorFactory(placeholder);
}
var result = validator(value, object, key, placeholder);
if (placeholder) {
// Remove from request object when finished
delete placeholder.add;
}
return result;
};
module.exports = new Types();

@@ -1,153 +0,157 @@

var util = require("util");
var BaseType = require("./base");
var Utils = require("../utils");
// Load modules
function NumberType() {
var NodeUtil = require('util');
var BaseType = require('./base');
var Utils = require('../utils');
NumberType.super_.call(this);
// Declare internals
var internals = {};
module.exports = internals.createType = function () {
return new internals.NumberType();
};
module.exports.NumberType = internals.NumberType = function () {
internals.NumberType.super_.call(this);
Utils.mixin(this, BaseType);
}
return this;
};
util.inherits(NumberType, BaseType);
NodeUtil.inherits(internals.NumberType, BaseType);
NumberType.prototype.__name = "Number";
NumberType.prototype.convert = function(value) {
internals.NumberType.prototype.__name = 'Number';
if (typeof value == "string") {
internals.NumberType.prototype.convert = function (value) {
if (typeof value === 'string') {
return Number(value);
}
else {
return value;
}
}
return value;
};
NumberType.prototype._empty = function(){
return function(value){
internals.NumberType.prototype._base = function () {
return isNaN(value); //(value === null);
}
}
return function (value, qs, key, req) {
NumberType.prototype._base = function() {
return function(value, qs, key, req) {
if (typeof value !== "number" && typeof value !== "string") {
if (typeof value !== 'number' && typeof value !== 'string') {
return false;
}
return !isNaN(+value);
};
}
};
NumberType.prototype.base = function() {
internals.NumberType.prototype.base = function () {
this.add('base', this._base(), arguments);
return this;
}
};
NumberType.prototype._min = function(n) {
Utils.assert((!isNaN(n) && ((n|0) == parseFloat(n))), "In Types.Number.min(n), the n must be an integer.");
return function(value, qs, key, req) {
internals.NumberType.prototype._min = function (n) {
Utils.assert((!isNaN(n) && ((n | 0) === parseFloat(n))), 'In Types.Number.min(n), the n must be an integer.');
return function (value, qs, key, req) {
req = req || {};
req.add = req.add || function(){};
req.add = req.add || function () { };
var result = (isNaN(value) || value >= n);
if (result === false) {
req.add("the value of `" + key + "` must be larger than (or equal to) " + n);
req.add('the value of `' + key + '` must be larger than (or equal to) ' + n);
}
return result;
};
}
};
NumberType.prototype.min = function(n) {
internals.NumberType.prototype.min = function (n) {
this.add('min', this._min(n), arguments);
return this;
}
};
NumberType.prototype._max = function(n) {
Utils.assert((!isNaN(n) && ((n|0) == parseFloat(n))), "In Types.Number.max(n), the n must be an integer.");
return function(value, qs, key, req) {
internals.NumberType.prototype._max = function (n) {
Utils.assert((!isNaN(n) && ((n | 0) === parseFloat(n))), 'In Types.Number.max(n), the n must be an integer.');
return function (value, qs, key, req) {
req = req || {};
req.add = req.add || function(){};
req.add = req.add || function () { };
var result = (value <= n);
if (result === false) {
req.add("the value of `" + key + "` must be less than (or equal to) " + n);
req.add('the value of `' + key + '` must be less than (or equal to) ' + n);
}
return result;
};
}
};
NumberType.prototype.max = function(n) {
internals.NumberType.prototype.max = function (n) {
this.add('max', this._max(n), arguments);
return this;
}
};
NumberType.prototype._integer = function() {
return function(value, qs, key, req) {
internals.NumberType.prototype._integer = function () {
return function (value, qs, key, req) {
req = req || {};
req.add = req.add || function(){};
var result = (!isNaN(value) && ((value|0) == parseFloat(value)));
req.add = req.add || function () { };
var result = (!isNaN(value) && ((value | 0) === parseFloat(value)));
if (result === false) {
req.add("the value of `" + key + "` must be an integer");
req.add('the value of `' + key + '` must be an integer');
}
return result;
};
}
};
NumberType.prototype.integer = function() {
internals.NumberType.prototype.integer = function () {
this.add('integer', this._integer(), arguments);
return this;
}
};
NumberType.prototype._float = function() {
internals.NumberType.prototype._float = function () {
var isInt = this._integer();
return function(value, qs, key, req) {
return function (value, qs, key, req) {
req = req || {};
req.add = req.add || function(){};
req.add = req.add || function () { };
var result = (!isInt(value));
if (result === false) {
req.add("the value of `" + key + "` must be a float or double");
req.add('the value of `' + key + '` must be a float or double');
}
return result;
};
}
};
NumberType.prototype.float = function() {
internals.NumberType.prototype.float = function () {
this.add('float', this._float(), arguments);
return this;
}
};
function CreateType() {
return new NumberType();
}
module.exports = CreateType;
module.exports.NumberType = NumberType;

@@ -1,41 +0,52 @@

var util = require("util");
var BaseType = require("./base");
var Utils = require("../utils");
// Load modules
function ObjectType() {
var NodeUtil = require('util');
var BaseType = require('./base');
var Utils = require('../utils');
ObjectType.super_.call(this);
// Declare internals
var internals = {};
module.exports = internals.createType = function () {
return new internals.ObjectType();
};
module.exports.ObjectType = internals.ObjectType = function () {
internals.ObjectType.super_.call(this);
Utils.mixin(this, BaseType);
}
return this;
};
util.inherits(ObjectType, BaseType);
NodeUtil.inherits(internals.ObjectType, BaseType);
ObjectType.prototype.__name = "Object";
ObjectType.prototype.convert = function(value) {
internals.ObjectType.prototype.__name = 'Object';
internals.ObjectType.prototype.convert = function (value) {
return JSON.parse(value);
}
};
ObjectType.prototype._base = function() {
return function(value) {
internals.ObjectType.prototype._base = function () {
return (value == null || typeof value == "object");
return function (value) {
return (value === null || typeof value === 'object');
};
}
};
ObjectType.prototype.base = function() {
internals.ObjectType.prototype.base = function () {
this.add('base', this._base(), arguments);
return this;
}
};
function CreateType() {
return new ObjectType();
}
module.exports = CreateType;
module.exports.ObjectType = ObjectType;

@@ -1,248 +0,189 @@

var util = require("util");
var BaseType = require("./base");
var ArrayType = require('./array').ArrayType;
var Email = require("./email");
var Utils = require("../utils");
// Load modules
function StringType() {
var NodeUtil = require('util');
var BaseType = require('./base');
var Utils = require('../utils');
var Email = require('./email');
StringType.super_.call(this);
Utils.mixin(this, BaseType);
}
util.inherits(StringType, BaseType);
// Declare internals
StringType.prototype.__name = "String";
var internals = {};
// TODO: move to base
// StringType.prototype.init = function() {
// for(var i in this){
// var pattern = /^[_]{1}([a-z0-9]+)$/;
// var matches = i.match(pattern);
module.exports = internals.createType = function () {
// if (matches) {
// var fnName = "x_" + matches[1];
// this[fnName] = function() {
// this.add(fnName, this[fnName](n), arguments);
// return this;
// }
// if (process.printed){ continue; }
// console.log(fnName)
// }
// }
// process.printed = true;
// return this;
// }
StringType.prototype.__defaultValids = [undefined];
StringType.prototype.__defaultInvalids = [null, ""];
return new internals.StringType();
};
// StringType.prototype.base = function() {
// var self = this;
// return function(value, qs, key, req) {
module.exports.StringType = internals.StringType = function () {
// // var valid = self.__valids.map(function(d){
// // return qs[key] == d;
// // }).indexOf(true) >= 0;
// // var invalid = self.__invalids.map(function(d){
// // return qs[key] == d;
// // }).indexOf(true) >= 0;
// // return valid && !invalid;
// // console.log(self.__invalids.map(function(d){return qs[key] == d;}));
// return true;
// }
// }
internals.StringType.super_.call(this);
Utils.mixin(this, BaseType);
return this;
};
StringType.prototype._base = function() {
NodeUtil.inherits(internals.StringType, BaseType);
return function(value, qs, key, req) {
return typeof value == "string";
internals.StringType.prototype.__name = 'String';
internals.StringType.prototype.__defaultValids = [undefined];
internals.StringType.prototype.__defaultInvalids = [null, ''];
// Deprecated code below should be moved to Array
// var keyDoesNotExist = !qs.hasOwnProperty(key);
// var valueIsMinLength = (qs[key] !== undefined && qs[key].length >= 1);
// var valueIsNotNumber = isNaN(+value) || isNaN((new Date(+value)).getTime());
// // req = req || {};
// // req.add = req.add || function(){};
// // var valueIsNotArray = !(value instanceof Array);
// var valueIsNotObject = true;
// if (typeof value !== "string") {
// valueIsNotObject = typeof value !== "object";
// }
// else {
// try {
// var v = JSON.parse(value);
// valueIsNotObject = (typeof v !== "object" && !(v instanceof Array))
// }
// catch (e) {
internals.StringType.prototype._base = function () {
// // console.log(e)
// }
// }
// var valueIsDefined = (keyDoesNotExist || valueIsMinLength);
// if (valueIsDefined === false) {
return function (value, qs, key, req) {
// req.add("the value of `" + key + "` is not allowed to be the empty string ('')");
// }
// var result = (valueIsDefined &&
// valueIsNotNumber &&
// valueIsNotObject);
// return result;
return typeof value === 'string';
};
}
};
StringType.prototype.base = function() {
this.add("base", this._base(), arguments);
internals.StringType.prototype.base = function () {
this.add('base', this._base(), arguments);
return this;
}
};
StringType.prototype.emptyOk = function() {
this.allow("");
this.__modifiers.add("emptyOk");
internals.StringType.prototype.emptyOk = function () {
this.allow('');
this.__modifiers.add('emptyOk');
return this;
}
};
StringType.prototype._min = function(n) {
Utils.assert((!isNaN(n) && ((n|0) == parseFloat(n))), "In Types.String.min(n), the n must be an integer.");
Utils.assert(n >= 0, "In Types.String.min(n), the n must be a non-negative integer.");
internals.StringType.prototype._min = function (n) {
return function(value, qs, key, req) {
Utils.assert((!isNaN(n) && ((n | 0) == parseFloat(n))), 'In Types.String.min(n), the n must be an integer.');
Utils.assert(n >= 0, 'In Types.String.min(n), the n must be a non-negative integer.');
this.__valids.remove(undefined);
return function (value, qs, key, req) {
req = req || {};
req.add = req.add || function(){};
req.add = req.add || function () { };
if (value === null || typeof value === "undefined") {
if (value === null || typeof value === 'undefined') {
return false;
}
var result = (value.length >= n);
if (result === false) {
req.add("the value of `" + key + "` must be at least " + n + " characters long");
req.add('the value of `' + key + '` must be at least ' + n + ' characters long');
}
return result;
};
}
};
StringType.prototype.min = function(n) {
this.add("min", this._min(n), arguments);
internals.StringType.prototype.min = function (n) {
this.add('min', this._min(n), arguments);
return this;
}
};
StringType.prototype._max = function(n) {
Utils.assert((!isNaN(n) && ((n|0) == parseFloat(n))), "In Types.String.max(n), the n must be an integer");
Utils.assert(n >= 0, "In Types.String.max(n), the n must be a non-negative integer");
return function(value, qs, key, req) {
internals.StringType.prototype._max = function (n) {
Utils.assert((!isNaN(n) && ((n | 0) == parseFloat(n))), 'In Types.String.max(n), the n must be an integer');
Utils.assert(n >= 0, 'In Types.String.max(n), the n must be a non-negative integer');
this.__valids.remove(undefined);
return function (value, qs, key, req) {
req = req || {};
req.add = req.add || function(){};
req.add = req.add || function () { };
var result = (value.length <= n);
if (result === false) {
req.add("the value of `" + key +"` must be less than (or equal to) " + n + " characters long");
req.add('the value of `' + key + '` must be less than (or equal to) ' + n + ' characters long');
}
return result;
};
}
};
StringType.prototype.max = function(n) {
this.add("max", this._max(n), arguments);
internals.StringType.prototype.max = function (n) {
this.add('max', this._max(n), arguments);
return this;
}
};
StringType.prototype._regex = function(n) {
Utils.assert(n instanceof RegExp, "In Types.String.regex(n), the n must be a RegExp");
return function(value, qs, key, req) {
internals.StringType.prototype._regex = function (n) {
Utils.assert(n instanceof RegExp, 'In Types.String.regex(n), the n must be a RegExp');
this.__valids.remove(undefined);
return function (value, qs, key, req) {
req = req || {};
req.add = req.add || function(){};
req.add = req.add || function () { };
var result = (value.match(n) !== null);
if (result === false) {
req.add("the value of `" + key + "` must match the RegExp `" + n.toString() + "`");
req.add('the value of `' + key + '` must match the RegExp `' + n.toString() + '`');
}
return result;
};
}
};
StringType.prototype.regex = function(pattern) {
internals.StringType.prototype.regex = function (pattern) {
this.add('regex', this._regex(pattern), arguments);
return this;
}
};
StringType.prototype._date = function(){
return function(value, qs, key, req){
internals.StringType.prototype._date = function () {
return function (value, qs, key, req) {
req = req || {};
req.add = req.add || function(){};
req.add = req.add || function () { };
value = (isNaN(Number(value)) === false) ? +value : value;
var converted = new Date(value);
var result = (!isNaN(converted.getTime()));
if (result === false) {
req.add("the value of `" + key + "` must be a valid JavaScript Date format");
req.add('the value of `' + key + '` must be a valid JavaScript Date format');
}
return result;
}
}
};
StringType.prototype.date = function(){
this.add('date', this._date.apply(arguments), arguments);
return this;
}
internals.StringType.prototype.date = function () {
StringType.prototype.alphanum = function(spacesEnabled) {
this.add('date', this._date.apply(arguments), arguments);
return this;
};
internals.StringType.prototype.alphanum = function (spacesEnabled) {
spacesEnabled = (spacesEnabled === null) ? true : spacesEnabled;
if (spacesEnabled === true) {
var pattern = /^[\w\s]+$/;
var pattern = null;
if (spacesEnabled) {
pattern = /^[\w\s]+$/;
}
else {
pattern = /^[a-zA-Z0-9]+$/;
}
var pattern = /^[a-zA-Z0-9]+$/;
}
this.regex(pattern);
return this;
}
};
StringType.prototype.email = function() {
internals.StringType.prototype.email = function () {
this.regex(Email._regex);
return this;
}
};
function CreateStringType() {
return new StringType();
}
module.exports = CreateStringType;
module.exports.StringType = StringType;

@@ -37,72 +37,1 @@ // Load modules

var Set = exports.Set = function (initialValue) {
this.inspect = require('sys').inspect;
this._values = [];
this._exists = {};
if (initialValue !== null && typeof initialValue !== "undefined") {
if (initialValue instanceof Array) {
for(var i = initialValue.length - 1; i >= 0; i--) {
this.add(initialValue[i]);
}
}
else {
// Error
console.log("given improper input to Set")
}
}
};
Set.prototype.add = function (value) {
var key = this.inspect(value);
if (!(this._exists.hasOwnProperty(key))) {
this._values.push(value);
this._exists[key] = this._values.length - 1;
}
};
Set.prototype.remove = function (value) {
var key = this.inspect(value);
if (this._exists.hasOwnProperty(key)) {
this._values.splice(this._exists[key], 1);
delete this._exists[key];
}
};
Set.prototype.get = function(){
return this._values;
}
Set.prototype.has = function(value) {
return this._exists.hasOwnProperty(this.inspect(value));
}
Set.prototype.valueOf = function(){
return this._values;
}
Set.prototype.toJSON =
Set.prototype.toString = function(){
return JSON.inspect(this.valueOf());
}
Set.prototype.map = function (fn) {
return this._values.map(fn);
};
{
"name": "joi",
"description": "Object schema validation",
"version": "0.0.5",
"version": "0.0.6",
"author": "Van Nguyen <the.gol.effect@gmail.com>",
"contributors":[
"Eran Hammer <eran@hueniverse.com> (http://hueniverse.com)"
"Eran Hammer <eran@hueniverse.com> (http://hueniverse.com)",
"Wyatt Preul <wpreul@gmail.com>"
],

@@ -23,4 +24,3 @@ "repository": "git://github.com/walmartlabs/joi",

"mocha": "1.x.x",
"should": "1.x.x",
"sinon": "1.3.4"
"chai": "1.0.x"
},

@@ -27,0 +27,0 @@ "scripts": {

@@ -1,3 +0,3 @@

joi
===
<a href="/walmartlabs/blammo"><img src="https://raw.github.com/walmartlabs/blammo/master/images/from.png" align="right" /></a>
# joi

@@ -7,1 +7,462 @@ Object schema validation

[![Build Status](https://secure.travis-ci.org/walmartlabs/joi.png)](http://travis-ci.org/walmartlabs/joi)
# Table of Contents
* [Introduction](#introduction "Introduction")
* [Type Registry](#type-registry "Type Registry")
* [Constraints](#constraints "Constraints")
* [BaseType](#basetype "BaseType")
* [String](#string "String")
* [Number](#number "Number")
* [Boolean](#boolean "Boolean")
* [Array](#array "Array")
* [Object](#object "Object")
* [Usage](#usage "Usage")
* [Config Syntax](#config-syntax "Config Syntax")
* [Evaluation Order](#evaluation-order "Evaluation Order")
* [Special Options](#special-options "Special Options")
* [Security Considerations](#security-considerations "Security Considerations")
* [References](#references "References")
* [Reference A: Other Types](#reference-a-other-types "Reference A: Other Types")
# Introduction
The **joi** validation system is used to validate JavaScript objects based on a rich descriptive schema.
Schema validation is the process of ensuring that objecta match pre-defined expectations.
For example, the following schema:
```javascript
var Joi = require('joi');
var schema = {
username: Joi.types.String().alphanum().min(3).max(30).with('birthyear').required(),
password: Joi.types.String().regex(/[a-zA-Z0-9]{3,30}/).without('access_token'),
access_token: Joi.types.String(),
birthyear: Joi.types.Number().min(1850).max(2012),
email: Joi.types.String().email()
};
```
defines these constraints:
* 'username'
* a required string
* must contain only alphanumeric characters
* at least 3 chars long but no more than 30
* must be accompanied by 'birthyear' (logical AND)
* 'password'
* an optional string
* must satisfy the custom regex
* cannot appear together with 'access_token'
* 'access_token'
* an optional, unconstrained string
* 'birthyear'
* an integer between 1850 and 2012
* 'email'
* a valid email address string
The above constraints point out some non-obvious features:
* Keys are optional by default
* Strings are by default utf-8 encoded
* relationships are defined in an additive fashion
* "X.join(Y), Y.join(Z)" is the same as requiring all three to be present: "X AND Y AND Z"
* Likewise "X.xor(Y), Y.xor(Z)" => requires that only one of three be present: "X XOR Y XOR Z"
* .regex may or may not override other string-related constraints (.alphanum, .min, .max)
** constraints are evaluated in order
* order of chained functions matter
** ".min(0).max(100).min(1)" sets the min to 1, overwriting the result of the first min call
** if ".regex(/[a-z]{0,3}/)" and ".max(50)" both supplied, only the overlap is valid (length 3 or less = valid)
# Type Registry
The Types object is pre-populated with a mutable list of JavaScript's valid data types. However, for convenience, the registry also includes subset helpers (marked with #):
* String
* Date ```String.date()```
* Email ```String.email()```
* Number
* Int ```Number.integer()```
* Float ```Number.float()```
* Boolean
* Array
* Object
* Function
Note that the Int is just Number with the integer constraint already applied. Any custom, user-defined data type is derived from one of the base types (although it may also combine additional types for sub-elements). Thus, there are two valid ways of creating your own types.
The first method is to add the type directly to the Type Registry. This makes the new type explicitly available as a base Type.
```javascript
var IntDef = _.extends({}, Number, function () {
// Constructor
return this.integer();
});
Types.set("Int", IntDef);
var Int = Types.Int;
```
The second, simpler, and more acceptable method is to alias the new Type within the config file.
```javascript
var PositiveInt = Number().integer().min(0)
PositiveInt.max(999999);
```
Thus, subsequent calls to the new "type" will behave as fully registered types in much less code.
*Note: The first method may eventually be deprecated. Then, the Type Registry becomes non-mutable which simplies the logic significantly.*
*Note: See "Reference A" before suggesting a pre-included Type for the Type Registry.*
## Constraints
Constraints are functions that restrict the input value in some way.
By default, all without explicit constraints, Types are optional.
### Implementation
```javascript
var schema = {
username: Joi.types.String().min(6).max(30).allow('admin').deny('Administrator'),
};
```
The above example demonstrates that even though the username has a minimum length of 6 extra constraints can be appended that allow 'admin' to be used as a username. Likewise, even though Administrator would be allowed by the other constraints, it is explicitly denied by the _'deny'_ constraint.
### By Type
#### BaseType
All types inherit the following builtin constraints:
##### BaseType.required()
Specifies that the input may not be undefined (unspecified).
##### BaseType.allow(value)
Specifies that the input may equal this value. This is type specific, so you cannot allow a number on a string type and vice-versa.
This function is idempotent.
*Note: This function does not verify that value is the correct type.*
##### BaseType.deny(value)
Specifies that the input may NOT equal this value.
This function is idempotent.
*Note: This function does not verify that value is the correct type.*
##### Basetype.valid(a1[, a2, ...])
Specifies an arbitrary number of valid values for this input.
If no inputs are supplied, it returns an Error.
If one or more of inputs given do not match the basic type, an Error is raised.
##### Basetype.invalid(a1[, a2, ...])
Specifies an arbitrary number of invalid values for this input.
If no inputs are supplied, it returns an Error.
If one or more of inputs given do not match the basic type, an Error is raised.
##### BaseType.with(a1[, a2, ...])
Specifies an arbitrary number of inputs that must also be supplied (a1..an) with this input.
*Note: This may or may not have aliases in the final version (.join, .with, .and... etc)*
##### BaseType.without(a1[, a2, ...])
Specifies an arbitrary number of inputs that cannot exist alongside this input (logical XOR).
*Note: This may or may not have aliases in the final version (.disjoin, .without, .xor... etc)*
##### BaseType.nullOk()
Specifies that the value is allowed to be null.
##### BaseType.rename(to[, options])
Specifies a key to rename the current parameter to.
Options take the form of an object with the follow default values:
```javascript
{
deleteOrig: false,
allowMult: false,
allowOverwrite: false
}
```
The option "deleteOrig" specifies whether or not to delete the original key of the param (effectively a permanent "move").
The option "allowMult" specifies whether or not multiple parameters can be renamed to a single key.
The option "allowOverwrite" specifies whether or not the rename function can overwrite existing keys.
#### String
Strings, by default, match JavaScript Strings. They are typically unbounded in length unless limited by interpreter. They are encoded in UTF-8 (this is true in Node.js at least). They may contain any allowable characters in the specified encoding.
The Type Registry's implementation of String also includes some builtin constraints:
##### String.emptyOk()
Specifies that the input may be equal to '' (the empty string).
##### String.min(n)
Specifies a minimum length for this input string, inclusive.
If n is not specified, it returns an Error.
If n is not a non-negative integer, it returns an Error.
##### String.max(n)
Specifies a maximum length for this input string, inclusive.
If n is not specified, it returns an Error.
If n is not a positive integer, it returns an Error.
##### String.alphanum()
Specifies that this input may only consist of alphanumeric characters.
##### String.regex(pattern)
Specifies that this input matches the given RegExp pattern.
If pattern is not specified, it returns an Error.
If pattern is not a valid RegExp object, it returns an error.
##### String.email()
Specifies that this input is a valid email string.
##### String.date()
Specifies that this input is a valid Date string (locale string but also accepts unix timestamp).
##### String.encoding(enc)
Specifies an explicit encoding for this input string.
*Warning: This may or may not be included in the final version. A better solution may be to forcibly convert from the encoding specified by enc to utf-8. However, this is not always possible (i.e. UTF-16 converting to UTF-8 would truncate a lot of characters).*
#### Number
##### Number.integer()
Specifies that this input be a valid integer.
##### Number.float()
Specifies that this input be a valid float or double.
##### Number.min(n)
Specifies a minimum value for this input, inclusive.
If n is not specified, it returns an Error.
If n is not a positive integer, it returns an Error.
##### Number.max(n)
Specifies a maximum value for this input, inclusive.
If n is not specified, it returns an Error.
If n is not a positive integer, it returns an Error.
#### Boolean
Boolean values accept a case-insensitive string parameter. If the value is "true", true is returned. Otherwise, false is returned.
*Note: Boolean has no special methods other than those inherited from BaseType*
#### Array
**Note**
Array values take the querystring form of
```
?cars=1&cars=2
```
and get converted to
```
{ cars: [ '1', '2' ] }
```
by the server.
*Note: Array has no special methods other than those inherited from BaseType*
##### Array.includes(n1, n2, ...)
Specifies allowed types for the array value to include. The values of n1, n2, ... are Type Registry constraints (usually of other types).
##### Array.excludes(n1, n2, ...)
Specifies allowed types for the array value to exclude. The values of n1, n2, ... are Type Registry constraints (usually of other types).
#### Object
*Note: Object has no special methods other than those inherited from BaseType*
## Usage
### Config Syntax
In Hapi's routes configuration array, the routes are listed as JavaScript objects. Route objects may include an optional "query" key, the value of which should be an object. This object should associate querystring input names to validation constraints.
```javascript
var queryObj = {
input_name: constraints
};
```
In the above code example, "input_name" must conform to typical JavaScript object key constraints (no spaces, no quotes unless escaped and surrounded by quotes, etc).
In place of "constraints", there should be a combination of constraints. The combination of constraints must be formed starting from a valid base type. The base type may be followed by zero or more pre-defined constraint functions chained consecutively. These combinations can be pre-combined into "alias" variables that may also be followed by zero or more pre-defined constraint functions chained consecutively. An example is shown below:
```javascript
Base().constraint_one().constraint_two()...
BaseAlias = Base().constraint()
BaseAlias.constraint_one().constraint_two()...
```
Constraint functions may accept optional and arbitrary parameters.
Every call must have its own `Base()` prefix. This creates a new validation object. Otherwise, it will retain settings from any prior constraints.
### Evaluation Order
#### Overrides
Each constraint is evaluated independantly and in order of chaining. In some cases, a subsequent constraint may override a prior constraint:
```javascript
String.required().optional() # This input will be considered optional
String.required(false).required() # This input will be considered required
```
Constraints that can override modify the query validation state upon the function's evocation. The actual evaluation is performed at the end of the chain (or once the entire querystring validation is finished).
These constraint functions are special cases:
* required/optional
* with/without
* rename
Rename is always performed at the end of the chain.
###### With/Without
Below is an example of a schema that is likely to be used for defining a username/password constraint. Notice that _'with'_ is used on the _'username'_ to indicate that _'password'_ is required to appear whenever _'username'_ exists. Similarly, _'password'_ has a constraint indicating that the key _'access_token'_ must not exist when _'password'_ exists.
```javascript
username: Joi.types.String().with('password'),
password: Joi.types.String().without('access_token')
```
#### Overrules
Yet, in another case, a prior constraint may overrule a subsequent constraint:
```javascript
Types.String().max(5).max(10) # This input cannot be larger than 5 characters
Types.String().max(3).regex(/.{0,5}/) # This input cannot be larger than 3 characters
```
This should apply to all other constraints that do not override.
## Special Options
Joi has special settings that will modify certain behaviors.
### Global
#### Skip Functions
On occasion, an object must be validated which contains functions as properties. To force Joi to ignore validation on such functions, use the `skipFunctions` option:
Joi.settings.skipFunctions = true;
#### Save Conversions
Through the process of validation, some inputs will be converted to accommodate the various constraint functions. For example, if an input is of type Joi.Types.Number() but is defined as a string, the validator will convert to Number during validation. This does not persist and does not affect the original input.
To force Joi to save the conversion, use the `saveConversions` option:
Joi.settings.saveConversions = true;
### Type-Specific
#### Short Circuit Breakout
When validating an input for a specific type with lots of constraints, Joi will, by default, return error immediately upon the first error condition. In some rare cases, iterating through all of the constraint functions is actually ideal (to identify all the reasons why an input is invalid at once). To force Joi to evaluate all constraints, use the `shortCircuit` option:
var S = Joi.Types.String();
S.options.shortCircuit = false;
var schema = {
nickname: S().valid('Silly').min(2)
}
schema.nickname.validate('o', null, null, errors) // => populates errors with all failing constraints
#### Non-Exclusive Valid
The `.valid` constraint is currently exclusive - if the input is NOT one of the values passed to `.valid`, the validator returns false. In the event this is too strict, use the hidden `__allowOnly` option.
var S = Joi.Types.String();
S.__allowOnly = false;
var schema = {
username: S().valid('walmart')
}
schema.username.validate('test') // => this returns true
## Security Considerations
Encodings could potentially play a role in security - some strings in one encoding, when exec()'d in another encoding could execute malicious code. If this type of validation is enabled, it will likely provide little to no explicit protection for developers. Developers could unintentionally (and even worse, unknowingly) expose a significant security risk.
## References
### Reference A: Other Types
#### "null"
The "null" variable is considered to be of type "object". An alias could easily be added for this type if necessary. However, for the purposes of querystring validation, this appears to be unnecessary.
#### "undefined"
Unlike null, undefined is its own type with its own special properties. For the purposes of querystring validation, any blank or indefinite inputs will appear as blank strings (""). As far as I know, there is no way to force the undefined object into the querystring. Thus, unless otherwise proven, "undefined" will not be included in the Type Registry.

@@ -1,11 +0,26 @@

var should = require("should");
// Load modules
var Chai = require('chai');
module.exports.verifyValidatorBehavior = function(typeObj, config, callback) {
for(var i in config){
var result = typeObj.validate(config[i][0]);
should.exist(result);
result.should.equal(config[i][1]);
}
callback();
}
// Declare internals
var internals = {};
// Test shortcuts
var expect = Chai.expect;
exports.verifyValidatorBehavior = function (typeObj, config, callback) {
for (var i in config) {
var result = typeObj.validate(config[i][0]);
expect(result).to.exist;
expect(result).to.equal(config[i][1]);
}
callback();
};

@@ -1,25 +0,67 @@

var Types = process.env.TEST_COV ? require('../../lib-cov/types') : require('../../lib/types');
var verifyBehavior = require("../support/meta").verifyValidatorBehavior;
var should = require("should");
// Load modules
describe("tests/types/array.js", function () {
var Chai = require('chai');
var Joi = process.env.TEST_COV ? require('../../lib-cov') : require('../../lib');
var Support = require('../support/meta');
describe("Types.Array", function () {
var A = Types.Array,
N = Types.Number,
S = Types.String;
it("should have mixins", function (done) {
// Declare internals
var internals = {};
// Test shortcuts
var expect = Chai.expect;
var verifyBehavior = Support.verifyValidatorBehavior;
describe('Types', function () {
describe('Array', function () {
var A = Joi.types.Array,
N = Joi.types.Number,
S = Joi.types.String;
it('should have mixins', function (done) {
var result = A();
should.exist(result.validate);
expect(result.validate).to.exist;
done();
});
describe("#validate", function () {
describe('#convert', function () {
it('should convert a string to an array', function (done) {
var result = A().convert('[1,2,3]');
expect(result.length).to.equal(3);
done();
});
it('should return a non array', function (done) {
var result = A().convert(3);
expect(result).to.equal(3);
done();
});
it('should convert a non-array string', function (done) {
var result = A().convert('3');
expect(result.length).to.equal(1);
done();
});
});
describe('#validate', function () {
it('should work', function (done) {
(function () {
expect(function () {
var arr = A();
var result = arr.validate([1]);
}).should.not.throw();
}).to.not.throw();
done();

@@ -29,2 +71,3 @@ });

it('should, by default, allow undefined, allow empty array', function (done) {
verifyBehavior(A(), [

@@ -39,3 +82,4 @@ [undefined, true],

it("should, when .required(), deny undefined", function (done) {
it('should, when .required(), deny undefined', function (done) {
verifyBehavior(A().required(), [

@@ -46,3 +90,21 @@ [undefined, false]

it("should validate array of Numbers", function (done) {
it('should allow empty arrays with emptyOk', function (done) {
verifyBehavior(A().emptyOk(), [
[undefined, true],
[[], true]
], done);
});
it('should exclude values when excludes is called', function (done) {
verifyBehavior(A().excludes(S()), [
[['2', '1'], false],
[['1'], false],
[[2], true]
], done);
});
it('should validate array of Numbers', function (done) {
verifyBehavior(A().includes(N()), [

@@ -58,3 +120,3 @@ [

[
["a", 1, 2],
['a', 1, 2],
false

@@ -65,3 +127,4 @@ ]

it("should validate array of mixed Numbers & Strings", function (done) {
it('should validate array of mixed Numbers & Strings', function (done) {
verifyBehavior(A().includes(N(), S()), [

@@ -77,7 +140,7 @@ [

[
[1, "a", 5, 10],
[1, 'a', 5, 10],
true
],
[
["walmart", "everydaylowprices", 5000],
['walmart', 'everydaylowprices', 5000],
true

@@ -88,3 +151,4 @@ ]

it("should not validate array of unallowed mixed types (Array)", function (done) {
it('should not validate array of unallowed mixed types (Array)', function (done) {
verifyBehavior(A().includes(N()), [

@@ -103,10 +167,12 @@ [

describe("#_exclude", function () {
it("should work", function (done) {
describe('#_exclude', function () {
it('should work', function (done) {
var validator = A()._excludes(N());
var n = [1, 2, "hippo"];
var n = [1, 2, 'hippo'];
var result = validator(n);
result.should.equal(false);
expect(result).to.equal(false);

@@ -116,5 +182,3 @@ var m = ['x', 'y', 'z'];

result2.should.equal(true);
expect(result2).to.equal(true);
done();

@@ -125,93 +189,1 @@ });

});
// describe("Types.Array", function(){
// var A = Types.Array;
// var N = Types.Number;
// // it('should instantiate separate copies on invocation', function(done){
// // var result1 = A().required();
// // var result2 = A();
// // Object.keys(result1).should.not.equal(Object.keys(result2));
// // done();
// // })
// it("should inherit functions from BaseType", function(done){
// var fns = ["required", "add"];
// for(var i in fns){
// should.exist(A()[fns[i]]);
// }
// done();
// })
// it("should show resulting object with #valueOf", function(done){
// var result = A();
// should.exist(result.valueOf());
// done();
// })
// describe("#includes", function(done){
// it('should exist', function(done){
// should.exist(A().includes);
// done();
// })
// })
// describe("#_includes", function(done){
// it('should validate on known good input', function(done){
// var input = [10, 20];
// var validators = A()._includes(N().min(5));
// for(var j in validators) {
// var result = validators[j](input);
// should.exist(result);
// result.should.be(true);
// }
// done();
// })
// it('should invalidate on known bad input', function(done){
// var input = [3, 1];
// var len = input.length;
// var validators = A()._includes(N().min(5));
// var isValid = true;
// for(var j in validators) {
// var result = validators[j](input);
// should.exist(result);
// result.should.be(false);
// }
// done();
// })
// })
// // describe("#_excludes", function(done){
// // it('should validate on known good input', function(done){
// // var input = [3, 1];
// // var validators = A()._excludes(N().min(5));
// // for(var j in validators) {
// // var result = validators[j](input);
// // should.exist(result);
// // result.should.be(true);
// // }
// // done();
// // })
// // it('should invalidate on known bad input', function(done){
// // var input = [10, 20];
// // var len = input.length;
// // var validators = A()._excludes(N().min(5));
// // var isValid = true;
// // for(var j in validators) {
// // var result = validators[j](input);
// // should.exist(result);
// // result.should.be(false);
// // }
// // done();
// // })
// // })
// });

@@ -1,216 +0,234 @@

var should = require("should");
// Load modules
var Types = process.env.TEST_COV ? require('../../lib-cov/types') : require('../../lib/types');
var BaseType = Types.Base;
var Utils = require("../../lib/utils");
var sys = require("sys");
var Chai = require('chai');
var Joi = process.env.TEST_COV ? require('../../lib-cov') : require('../../lib');
describe("types/base.js", function () {
describe("BaseType", function () {
it('should', function (done) {
var B = new BaseType();
var r = B.allow(undefined);
// console.log("after allow", r);
done();
})
})
})
// describe("BaseType", function(){
// describe("#_required", function(){
// it('should return true if non-null input is given and required', function(done){
// var base = new BaseType();
// var result = base._required()("walmart");
// should.exist(result);
// result.should.equal(true);
// done();
// })
// Declare internals
// it('should return true if null input is given and allowNull is true', function(done){
// var base = new BaseType();
// var result = base._required(true)(null);
// should.exist(result);
// result.should.equal(true);
// done();
// })
var internals = {};
// it('should return false if null input is given and allowNull is false', function(done){
// var base = new BaseType();
// var result = base._required(false)(null);
// should.exist(result);
// result.should.equal(false);
// done();
// })
// it('should return false if no input is given and allowNull is false', function(done){
// var base = new BaseType();
// var result = base._required(false)();
// should.exist(result);
// result.should.equal(false);
// done();
// })
// })
// Test shortcuts
// describe("#_rename", function(){
// var key = "name";
// var key2 = "note";
// var key3 = "username";
// var qstr = {name: "van", note: "author"};
// var value = qstr[key];
// var value2 = qstr[key2];
var expect = Chai.expect;
// it("should alias a variable with default options", function(done){
// var base = new BaseType();
// var validator = base._rename(key3);
// var q = Utils.clone(qstr);
// var result = validator(value, q, key);
// should.exist(q[key3]);
// q[key3].should.equal(value);
// done();
// })
describe('Types', function () {
// it("should move variable if deleteOrig set", function(done){
// var base = new BaseType();
// var validator = base._rename(key3, {deleteOrig: true});
// var q = Utils.clone(qstr);
// var result = validator(value, q, key);
describe('Base', function () {
// should.exist(q[key3]);
// should.not.exist(q[key]);
// q[key3].should.equal(value);
// done();
// })
var B = Joi.types.Base;
// it("should overwrite existing variable if allowOverwrite set", function(done){
// var base = new BaseType();
// var key2 = "note";
// var validator = base._rename(key2, {allowOverwrite: true});
// var q = Utils.clone(qstr);
// var result = validator(value, q, key)
describe('#toString', function () {
// should.exist(q[key2]);
// q[key2].should.equal(value);
// q[key].should.equal(value);
// done();
// })
it('should return JSON string of values', function (done) {
// it("should not overwrite existing variable if allowOverwrite not set", function(done){
// var base = new BaseType();
// var validator = base._rename(key2, {allowOverwrite: false});
// var q = Utils.clone(qstr);
// var result = validator(value, q, key);
var b = new B().valid('test');
// should.exist(result);
// result.should.equal(false);
expect(b.toString()).to.include('test');
done();
});
});
// should.exist(q[key2]);
// q[key2].should.equal(value2);
// q[key].should.equal(value); // Original value not deleted
// done();
// })
describe('#add', function () {
// it("should not allow two renames to set the same key if allowMult not set", function(done){
// var base = new BaseType();
// var q = Utils.clone(qstr);
// var validator = base._rename(key3, {allowMult: false})
// var result = validator(value, q, key);
it('should throw an error when null is passed in', function (done) {
// var validator = base._rename(key3, {allowMult: false})
// var result = validator(value2, q, key2);
expect(function () {
// result.should.equal(false);
var b = new B();
var result = b.add(null);
}).to.throw;
done();
});
// // first _rename will not be rolled back
// should.exist(q[key3]);
// q[key3].should.equal(value);
// done();
// })
// })
it('should not throw an error when valid values are provided', function (done) {
// describe("#description", function(){
// it('should set description', function(done){
// var value = "walmart";
// var base = new BaseType();
// var result;
// (function(){
// result = base.description(value);
// }).should.not.throw();
// should.exist(result);
// result.description.should.equal(value);
// done();
// })
expect(function () {
// it('should return error if description is not a string', function(done){
// var value = 1;
// var base = new BaseType();
// var result;
// (function(){
// result = base.description(value);
// }).should.throw();
// // should.exist(result);
// // result.description.should.equal(value);
// done();
// })
// })
var b = new B();
var result = b.add('test', true);
}).to.not.throw;
done();
});
});
// describe("#notes", function(){
// it('should set notes if given as string', function(done){
// var value = "walmart";
// var base = new BaseType();
// var result;
// (function(){
// result = base.notes(value);
// }).should.not.throw();
// should.exist(result);
// result.notes.should.equal(value);
// done();
// })
describe('#exists', function () {
// it('should set notes if given as array', function(done){
// var value = ["walmart", "@walmartlabs"];
// var base = new BaseType();
// var result;
// (function(){
// result = base.notes(value);
// }).should.not.throw();
// should.exist(result);
// result.notes.should.equal(value);
// done();
// })
it('should return false when null is passed in', function (done) {
// it('should return error if not given as string or array', function(done){
// var value = 1;
// var base = new BaseType();
// var result;
// (function(){
// result = base.notes(value);
// }).should.throw();
// done();
// })
// })
var b = new B();
var result = b.exists(null);
// describe("#tags", function(){
// it('should set tags if given as array', function(done){
// var value = ["walmart", "@walmartlabs"];
// var base = new BaseType();
// var result;
// (function(){
// result = base.tags(value);
// }).should.not.throw();
// should.exist(result);
// result.tags.should.equal(value);
// done();
// })
expect(result).to.equal(false);
done();
});
// it('should return error if not given as array', function(done){
// var value = 1;
// var base = new BaseType();
// var result;
// (function(){
// result = base.notes(value);
// }).should.throw();
// done();
// })
// })
// })
it('should return true when passed true', function (done) {
var b = new B();
var result = b.exists(true);
expect(result).to.equal(true);
done();
});
});
describe('#with', function () {
it('should set related check', function (done) {
var b1 = new B();
var b2 = new B();
var result = b1.with(b2);
expect(result.__checks).to.include('with');
done();
});
it('should return false when related type not found', function (done) {
var b1 = new B();
var b2 = new B();
var result = b1.with(b2);
expect(result.validate('test')).to.equal(false);
done();
});
it('should return true when peers are null', function (done) {
var b1 = new B();
var result = b1._with(null);
expect(result(null)).to.equal(true);
done();
});
});
describe('#without', function () {
it('should set related check', function (done) {
var b1 = new B();
var b2 = new B();
var result = b1.without(b2);
expect(result.__checks).to.include('without');
done();
});
it('should return true when related type not found', function (done) {
var b1 = new B();
var b2 = new B();
var result = b1.without(b2);
expect(result.validate('test')).to.equal(true);
done();
});
});
describe('#rename', function () {
it('should rename the type', function (done) {
var b = new B();
var result = b.rename('test');
expect(result.validate('test')).to.equal(true);
done();
});
it('using allowMult enabled should allow renaming multiple times', function (done) {
var b = new B();
var result = b.rename('test1', { allowMult: true });
expect(result.validate({ test: true }, { test: true }, 'test', { add: function () { }, _renamed: { test1: true } })).to.equal(true);
done();
});
it('with allowMult disabled should not allow renaming multiple times', function (done) {
var b = new B();
var result = b.rename('test1', { allowMult: false });
expect(result.validate({ test: true }, { test: true }, 'test', { add: function () { }, _renamed: { test1: true } })).to.equal(false);
done();
});
it('with allowOverwrite disabled should not allow overwriting existing value', function (done) {
var b = new B();
var result = b.rename('test1', { allowOverwrite: false });
expect(result.validate({ test1: true }, { test1: true }, { test1: true })).to.equal(false);
done();
});
it('with allowOverwrite enabled should allow overwriting existing value', function (done) {
var b = new B();
var result = b.rename('test1', { allowOverwrite: true, deleteOrig: true });
expect(result.validate({ test1: true }, { test1: true }, { test1: true })).to.equal(true);
done();
});
});
describe('#description', function () {
it('sets the description', function (done) {
var b = new B();
b.description('my description');
expect(b.description).to.equal('my description');
done();
});
});
describe('#notes', function () {
it('sets the notes', function (done) {
var b = new B();
b.notes('my notes');
expect(b.notes).to.equal('my notes');
done();
});
});
describe('#tags', function () {
it('sets the tags', function (done) {
var b = new B();
b.tags(['tag1', 'tag2']);
expect(b.tags).to.include('tag1');
expect(b.tags).to.include('tag2');
done();
});
});
describe('#RequestErrorFactory', function () {
it('adds the error to the request object', function (done) {
var b = new B();
var err = new Error('my message');
var req = {};
b.RequestErrorFactory(req)(err);
expect(req.validationErrors).to.include('[ValidationError]: Error: my message');
done();
});
});
});
});

@@ -1,12 +0,129 @@

var Types = process.env.TEST_COV ? require('../../lib-cov/types') : require('../../lib/types');
var should = require("should");
// Load modules
describe("Types.Boolean", function () {
var B = Types.Boolean;
it("should have mixins", function (done) {
var result = B();
var Chai = require('chai');
var Joi = process.env.TEST_COV ? require('../../lib-cov') : require('../../lib');
var Support = require('../support/meta');
should.exist(result.validate);
done();
})
})
// Declare internals
var internals = {};
var verifyBehavior = Support.verifyValidatorBehavior;
// Test shortcuts
var expect = Chai.expect;
describe('Types', function () {
describe('Boolean', function () {
var B = Joi.types.Boolean;
it('should have mixins', function (done) {
var result = B();
expect(result.validate).to.exist;
done();
});
describe('#convert', function () {
it('should convert a string to a boolean', function (done) {
var result = B().convert('true');
expect(result).to.equal(true);
done();
});
it('should not convert a number to a boolean', function (done) {
var result = B().convert(1);
expect(result).to.equal(1);
done();
});
});
describe('#validate', function () {
it('should handle work with nullOk', function (done) {
var rule = B().nullOk();
verifyBehavior(rule, [
['1234', false],
[false, true],
[null, true]
], done);
});
it('should handle work with required', function (done) {
var rule = B().required();
verifyBehavior(rule, [
['1234', false],
['true', false],
[false, true],
[true, true],
[null, false]
], done);
});
it('should handle work with allow', function (done) {
var rule = B().allow(false);
verifyBehavior(rule, [
['1234', false],
[false, true],
[null, false]
], done);
});
it('should handle work with deny', function (done) {
var rule = B().deny(false);
verifyBehavior(rule, [
['1234', false],
[false, false],
[true, true],
[null, false]
], done);
});
it('should handle work with deny and nullOk', function (done) {
var rule = B().deny(false).nullOk();
verifyBehavior(rule, [
['1234', false],
[false, false],
[true, true],
[null, true]
], done);
});
it('should handle work with allow and deny', function (done) {
var rule = B().deny(true).allow(false);
verifyBehavior(rule, [
['1234', false],
[false, true],
[true, false],
[null, false]
], done);
});
it('should handle work with allow, deny, and nullOk', function (done) {
var rule = B().deny(true).allow(false).nullOk();
verifyBehavior(rule, [
['1234', false],
[false, true],
[true, false],
[null, true]
], done);
});
});
});
});

@@ -1,36 +0,93 @@

var Types = process.env.TEST_COV ? require('../../lib-cov/types') : require('../../lib/types');
var should = require("should");
// Load modules
describe("Types", function () {
it("should have a String key", function(done) {
Types.String.should.exist;
var Chai = require('chai');
var Joi = process.env.TEST_COV ? require('../../lib-cov') : require('../../lib');
// Declare internals
var internals = {};
// Test shortcuts
var expect = Chai.expect;
describe('Types', function () {
it('should have a String key', function (done) {
expect(Joi.types.String).to.exist;
done();
});
it("should have a Number key", function(done) {
Types.Number.should.exist;
it('should have a Number key', function (done) {
expect(Joi.types.Number).to.exist;
done();
});
it("should have a Boolean key", function(done) {
Types.Boolean.should.exist;
it('should have a Boolean key', function (done) {
expect(Joi.types.Boolean).to.exist;
done();
});
it("should have an Array key", function(done) {
Types.Array.should.exist;
it('should have an Array key', function (done) {
expect(Joi.types.Array).to.exist;
done();
});
describe("#validate", function() {
it("should validate a string value on an object", function(done) {
describe('#validate', function () {
it('should validate a string value on an object', function (done) {
var object = {
testme: "valid"
testme: 'valid'
};
var validator = function() { return true; };
Types.validate("testme", "String", object, validator).should.equal(true);
var validator = function () {
return true;
};
expect(Joi.types.validate('testme', 'String', object, validator)).to.equal(true);
done();
});
it('should convert a value and validate it', function (done) {
var object = {
testme: '1'
};
var validator = function (val) {
return val;
};
expect(Joi.types.validate('testme', 'Number', object, validator)).to.equal(1);
done();
});
it('should use a placeholder when its provided', function (done) {
var object = {
testme: '1'
};
var placeholder = {};
var validator = function (val) {
return val;
};
expect(Joi.types.validate('testme', 'Number', object, validator, placeholder)).to.equal(1);
expect(placeholder.validationErrors).to.exist;
done();
});
});
});

@@ -1,82 +0,362 @@

var Types = process.env.TEST_COV ? require('../../lib-cov/types') : require('../../lib/types');
var should = require("should");
var verifyBehavior = require("../support/meta").verifyValidatorBehavior;
// Load modules
describe("test/types/number.js", function () {
describe("Types.Number", function () {
var N = Types.Number;
var Chai = require('chai');
var Joi = process.env.TEST_COV ? require('../../lib-cov') : require('../../lib');
var Support = require('../support/meta');
it("should have mixins", function (done) {
var result = N();
should.exist(result.validate);
// Declare internals
var internals = {};
// Test shortcuts
var expect = Chai.expect;
var verifyBehavior = Support.verifyValidatorBehavior;
describe('Number', function () {
var N = Joi.types.Number;
it('should have mixins', function (done) {
var result = N();
expect(result.validate).to.exist;
done();
});
describe('#validate', function () {
it('should work', function (done) {
expect(function () {
var num = N();
var result = num.validate(100);
}).to.not.throw;
done();
});
describe("#validate", function () {
it('should work', function (done) {
(function () {
var num = N();
var result = num.validate(100);
}).should.not.throw();
done();
});
it('should, by default, allow undefined', function (done) {
it('should, by default, allow undefined', function (done) {
verifyBehavior(N(), [
[undefined, true]
], done);
});
verifyBehavior(N(), [
[undefined, true]
], done);
});
it("should, when .required(), deny undefined", function (done) {
verifyBehavior(N().required(), [
[undefined, false]
], done);
});
it('should, when .required(), deny undefined', function (done) {
it("should return false for denied value", function (done) {
var text = N().deny(50);
var result = text.validate(50);
should.exist(result);
result.should.equal(false);
done();
});
})
})
})
verifyBehavior(N().required(), [
[undefined, false]
], done);
});
describe("Types.Number", function () {
var N = Types.Number;
it('should return false for denied value', function (done) {
var text = N().deny(50);
var result = text.validate(50);
expect(result).to.exist;
expect(result).to.equal(false);
done();
});
it('should validate float', function (done) {
var t = N().float();
verifyBehavior(t, [
[100, false],
[0, false],
[null, false],
[1.02, true],
[0.01, true]
], done);
});
it('should validate integer', function (done) {
var t = N().integer();
verifyBehavior(t, [
[100, true],
[0, true],
[null, false],
[1.02, false],
[0.01, false]
], done);
});
it('should validate empty', function (done) {
var t = N().empty();
verifyBehavior(t, [
[NaN, false],
[null, true]
], done);
});
it('can convert strings to numbers', function (done) {
var t = N();
verifyBehavior(t, [
['1', true],
['100', true]
], done);
});
it('required validates correctly', function (done) {
var t = N().required();
verifyBehavior(t, [
[NaN, false],
['100', true]
], done);
});
it('convert will convert a string to a number', function (done) {
var t = N().convert('1');
expect(t).to.equal(1);
done();
});
it('convert will not convert a null', function (done) {
var t = N().convert(null);
expect(t).to.not.exist;
done();
});
it('should handle combination of min and max', function (done) {
var rule = N().min(8).max(10);
verifyBehavior(rule, [
[1, false],
[11, false],
[8, true],
[9, true],
[null, false]
], done);
});
it('should handle combination of min, max, and nullOk', function (done) {
var rule = N().min(8).max(10).nullOk();
verifyBehavior(rule, [
[1, false],
[11, false],
[8, true],
[9, true],
[null, true]
], done);
});
it('should handle combination of min, max, and allow', function (done) {
var rule = N().min(8).max(10).allow(1);
verifyBehavior(rule, [
[1, true],
[11, false],
[8, true],
[9, true],
[null, false]
], done);
});
it('should handle combination of min, max, allow, and nullOk', function (done) {
var rule = N().min(8).max(10).allow(1).nullOk();
verifyBehavior(rule, [
[1, true],
[11, false],
[8, true],
[9, true],
[null, true]
], done);
});
it('should handle combination of min, max, allow, and deny', function (done) {
var rule = N().min(8).max(10).allow(1).deny(9);
verifyBehavior(rule, [
[1, true],
[11, false],
[8, true],
[9, false],
[null, false]
], done);
});
it('should handle combination of min, max, allow, deny, and nullOk', function (done) {
var rule = N().min(8).max(10).allow(1).deny(9).nullOk();
verifyBehavior(rule, [
[1, true],
[11, false],
[8, true],
[9, false],
[null, true]
], done);
});
it('should handle combination of min, max, and float', function (done) {
var rule = N().min(8).max(10).float();
verifyBehavior(rule, [
[1, false],
[11, false],
[8, false],
[9, false],
[9.1, true],
[null, false]
], done);
});
it('should handle combination of min, max, float, and allow', function (done) {
var rule = N().min(8).max(10).float().allow(9);
verifyBehavior(rule, [
[1, false],
[11, false],
[8, false],
[9, true],
[9.1, true],
[null, false]
], done);
});
it('should handle combination of min, max, float, and deny', function (done) {
var rule = N().min(8).max(10).float().deny(9.1);
verifyBehavior(rule, [
[1, false],
[11, false],
[8, false],
[9, false],
[9.1, false],
[9.2, true],
[null, false]
], done);
});
it('should handle combination of min, max, float, allow, and deny', function (done) {
var rule = N().min(8).max(10).float().allow(9).deny(9.1);
verifyBehavior(rule, [
[1, false],
[11, false],
[8, false],
[9, true],
[9.1, false],
[9.2, true],
[null, false]
], done);
});
it('should handle combination of min, max, float, allow, deny, and nullOk', function (done) {
var rule = N().min(8).max(10).float().allow(9).deny(9.1).nullOk();
verifyBehavior(rule, [
[1, false],
[11, false],
[8, false],
[9, true],
[9.1, false],
[9.2, true],
[null, true]
], done);
});
it('should handle combination of min, max, and integer', function (done) {
var rule = N().min(8).max(10).integer();
verifyBehavior(rule, [
[1, false],
[11, false],
[8, true],
[9, true],
[9.1, false],
[null, false]
], done);
});
it('should handle combination of min, max, integer, and allow', function (done) {
var rule = N().min(8).max(10).integer().allow(9.1);
verifyBehavior(rule, [
[1, false],
[11, false],
[8, true],
[9, true],
[9.1, true],
[9.2, false],
[null, false]
], done);
});
it('should handle combination of min, max, integer, allow, and deny', function (done) {
var rule = N().min(8).max(10).integer().allow(9.1).deny(8);
verifyBehavior(rule, [
[1, false],
[11, false],
[8, false],
[9, true],
[9.1, true],
[9.2, false],
[null, false]
], done);
});
it('should handle combination of min, max, integer, allow, deny, and nullOk', function (done) {
var rule = N().min(8).max(10).integer().allow(9.1).deny(8).nullOk();
verifyBehavior(rule, [
[1, false],
[11, false],
[8, false],
[9, true],
[9.1, true],
[9.2, false],
[null, true]
], done);
});
});
it('should instantiate separate copies on invocation', function (done) {
var result1 = N().min(5);
var result2 = N().max(5);
Object.keys(result1).should.not.equal(Object.keys(result2));
expect(Object.keys(result1)).to.not.equal(Object.keys(result2));
done();
})
});
it("should inherit functions from BaseType", function (done) {
var fns = ["required", "add"];
it('should inherit functions from BaseType', function (done) {
var fns = ['required', 'add'];
for (var i in fns) {
should.exist(N()[fns[i]]);
expect(N()[fns[i]]).to.exist;
}
done();
})
});
it("should show resulting object with #valueOf", function (done) {
it('should show resulting object with #valueOf', function (done) {
var result = N().min(5);
should.exist(result.valueOf());
expect(result.valueOf()).to.exist;
done();
})
});
describe("#min", function (done) {
describe('#min', function () {
it('should exist', function (done) {
should.exist(N().min);
expect(N().min).to.exist;
done();
});
it("should have corresponding validator function", function (done) {
should.exist(N()._min);
it('should have corresponding validator function', function (done) {
expect(N()._min).to.exist;
done();

@@ -86,5 +366,6 @@ });

describe("#_min", function (done) {
describe('#_min', function () {
it('should validate on known valid input', function (done) {
// var inputs = ["abcde", "fghij", "klmnopqrstuv"];
var inputs = [5, 6, 7, 8, 9];

@@ -94,4 +375,4 @@ var validator = N()._min(5);

var currentResult = validator(inputs[i]);
should.exist(currentResult);
currentResult.should.equal(true);
expect(currentResult).to.exist;
expect(currentResult).to.equal(true);
}

@@ -102,3 +383,3 @@ done();

it('should invalidate on known invalid inputs', function (done) {
// var inputs = ["abc", "de", ""];
var inputs = [0, 1, 2, 3, 4];

@@ -108,4 +389,4 @@ var validator = N()._min(5);

var currentResult = validator(inputs[i]);
should.exist(currentResult);
currentResult.should.equal(false);
expect(currentResult).to.exist;
expect(currentResult).to.equal(false);
}

@@ -116,10 +397,12 @@ done();

describe("#max", function (done) {
describe('#max', function () {
it('should exist', function (done) {
should.exist(N().max);
expect(N().max).to.exist;
done();
});
it("should have corresponding validator function", function (done) {
should.exist(N()._max);
it('should have corresponding validator function', function (done) {
expect(N()._max).to.exist;
done();

@@ -129,5 +412,6 @@ });

describe("#_max", function (done) {
describe('#_max', function () {
it('should validate on known valid input', function (done) {
// var inputs = ["abc", "de", ""];
var inputs = [0, 1, 2, 3, 4];

@@ -137,10 +421,10 @@ var validator = N()._max(4);

var currentResult = validator(inputs[i]);
should.exist(currentResult);
currentResult.should.equal(true);
expect(currentResult).to.exist;
expect(currentResult).to.equal(true);
}
done();
})
});
it('should invalidate on known invalid inputs', function (done) {
// var inputs = ["abcde", "fghij", "klmnopqrstuv"];
var inputs = [5, 6, 7, 8];

@@ -150,8 +434,8 @@ var validator = N()._max(4);

var currentResult = validator(inputs[i]);
should.exist(currentResult);
currentResult.should.equal(false);
expect(currentResult).to.exist;
expect(currentResult).to.equal(false);
}
done();
})
})
})
});
});
});

@@ -1,298 +0,868 @@

var Types = process.env.TEST_COV ? require('../../lib-cov/types') : require('../../lib/types');
var should = require("should");
var verifyBehavior = require("../support/meta").verifyValidatorBehavior;
// Load modules
var Chai = require('chai');
var Joi = process.env.TEST_COV ? require('../../lib-cov') : require('../../lib');
var Support = require('../support/meta');
describe("test/types/string.js", function () {
describe("Types.String", function () {
var S = Types.String;
it("should have mixins", function (done) {
var result = S();
// Declare internals
should.exist(result.validate);
var internals = {};
// Test shortcuts
var expect = Chai.expect;
var verifyBehavior = Support.verifyValidatorBehavior;
describe('Joi.types.String', function () {
var S = Joi.types.String;
it('should have mixins', function (done) {
var result = S();
expect(result.validate).to.exist;
done();
});
it('should instantiate separate copies on invocation', function (done) {
var result1 = S().min(5);
var result2 = S().max(5);
expect(Object.keys(result1)).to.not.equal(Object.keys(result2));
done();
});
describe('#valid', function () {
it('should throw error on input not matching type', function (done) {
expect(function () {
S().valid(1);
}).to.throw;
done();
});
it("should instantiate separate copies on invocation", function (done) {
var result1 = S().min(5);
var result2 = S().max(5);
it('should not throw on input matching type', function (done) {
Object.keys(result1).should.not.equal(Object.keys(result2));
expect(function () {
S().valid('walmart');
}).to.not.throw;
done();
});
});
describe("#valid", function () {
it("should throw error on input not matching type", function (done) {
(function () {
S().valid(1);
}).should.throw();
done();
});
describe('#invalid', function () {
it("should not throw on input matching type", function (done) {
(function () {
S().valid("walmart");
}).should.not.throw();
done();
});
it('should throw error on input not matching type', function (done) {
expect(function () {
S().invalid(1);
}).to.throw;
done();
});
describe("#invalid", function () {
it("should throw error on input not matching type", function (done) {
(function () {
S().invalid(1);
}).should.throw();
done();
});
it('should not throw on input matching type', function (done) {
it("should not throw on input matching type", function (done) {
(function () {
S().invalid("walmart");
}).should.not.throw();
done();
});
expect(function () {
S().invalid('walmart');
}).to.not.throw;
done();
});
});
describe("#validate", function () {
it('should work', function (done) {
(function () {
var text = S();
var result = text.validate("joi");
}).should.not.throw();
done();
});
describe('#validate', function () {
it('should, by default, allow undefined, deny empty string', function (done) {
var conditions = [
[undefined, true],
["", false]
];
verifyBehavior(S(), conditions, done);
});
it('should work', function (done) {
it("should, when .required(), deny undefined, deny empty string", function (done) {
var t = S().required();
verifyBehavior(t, [
[undefined, false],
["", false]
], done);
});
expect(function () {
it("should return false for denied value", function (done) {
var text = S().deny("joi");
var result = text.validate("joi");
should.exist(result);
result.should.equal(false);
done();
});
var text = S();
var result = text.validate('joi');
}).to.not.throw;
done();
});
it("should return true for allowed value", function (done) {
var text = S().allow("hapi");
var result = text.validate("result");
should.exist(result);
result.should.equal(true);
done();
});
it('should, by default, allow undefined, deny empty string', function (done) {
it("should validate with one validator (min)", function (done) {
var text = S().min(3);
var result = text.validate("walmart");
should.exist(result);
result.should.equal(true);
done();
});
var conditions = [
[undefined, true],
['', false]
];
verifyBehavior(S(), conditions, done);
});
it("should validate with two validators (min, required)", function (done) {
var text = S().min(3).required();
var result = text.validate("walmart")
should.exist(result);
result.should.equal(true);
it('should, when .required(), deny undefined, deny empty string', function (done) {
var result2 = text.validate();
should.exist(result2);
result2.should.equal(false);
var t = S().required();
verifyBehavior(t, [
[undefined, false],
['', false]
], done);
});
done();
});
it('should, when .required(), validate non-empty strings', function (done) {
it("should validate null with nullOk()", function (done) {
verifyBehavior(S().nullOk(), [
[null, true]
], done);
});
var t = S().required();
verifyBehavior(t, [
['test', true],
['0', true],
[null, false]
], done);
});
it("should validate '' (empty string) with emptyOk()", function (done) {
verifyBehavior(S().emptyOk(), [
['', true],
["", true]
], done);
});
it('should validate invalid values', function (done) {
var t = S().invalid('a', 'b', 'c');
verifyBehavior(t, [
['x', true],
['a', false],
['c', false]
], done);
});
});
});
// describe("Types.String", function(){
// var S = Types.String;
it('should invalid undefined if min set', function (done) {
// it('should instantiate separate copies on invocation', function(done){
// var result1 = S().min(5);
// var result2 = S().max(5);
var t = S().min(3);
verifyBehavior(t, [
[undefined, false]
], done);
});
// Object.keys(result1).should.not.equal(Object.keys(result2));
// done();
// })
it('should invalid undefined if max set', function (done) {
// it("should inherit functions from BaseType", function(done){
// var fns = ["required", "add"];
var t = S().max(3);
verifyBehavior(t, [
[undefined, false]
], done);
});
// for(var i in fns){
// should.exist(S()[fns[i]]);
// }
// done();
// })
it('should invalidate invalid values', function (done) {
// it("should show resulting object with #valueOf", function(done){
// var result = S().min(5);
// should.exist(result.valueOf());
// done();
// })
var t = S().valid('a', 'b', 'c');
verifyBehavior(t, [
['x', false],
['a', true],
['c', true]
], done);
});
// // describe("#_base", function(){
// // it("should work", function(done){
// // var fn = S()._base();
// // fn._valids = []
// // var result = fn()
// // done();
// // })
// // })
it('should validate minimum length when min is used', function (done) {
// describe("#min", function(done){
// it('should exist', function(done){
// should.exist(S().min);
// done();
// })
var t = S().min(3);
verifyBehavior(t, [
['test', true],
['0', false],
[null, false]
], done);
});
// it("should have corresponding validator function", function(done){
// should.exist(S()._min);
// done();
// })
it('should validate minimum length when min is 0', function (done) {
// it('should have value on #valueOf', function(done){
// var result = S().min(5).valueOf();
// should.exist(result);
// (result.length).should.equal(2)
// done();
// })
// })
var t = S().min(0);
verifyBehavior(t, [
['0', true],
[null, false],
[undefined, false]
], done);
});
// describe("#_min", function(done){
// it('should validate on known valid input', function(done){
// var inputs = ["abcde", "fghij", "klmnopqrstuv"];
// var validator = S()._min(5);
// for(var i in inputs){
// var currentResult = validator(inputs[i]);
// should.exist(currentResult);
// currentResult.should.equal(true);
// }
// done();
// })
it('should return false with minimum length and a null value passed in', function (done) {
// it('should invalidate on known invalid inputs', function(done){
// var inputs = ["abc", "de", ""];
// var validator = S()._min(5);
// for(var i in inputs){
// var currentResult = validator(inputs[i]);
// should.exist(currentResult);
// currentResult.should.equal(false);
// }
// done();
// })
// })
var t = S()._min(3);
expect(t(null)).to.equal(false);
done();
});
// describe("#max", function(done){
// it('should exist', function(done){
// should.exist(S().max);
// done();
// })
it('nullOk overrides min length requirement', function (done) {
// it("should have corresponding validator function", function(done){
// should.exist(S()._max);
// done();
// })
var t = S().min(3).nullOk();
verifyBehavior(t, [
[null, true]
], done);
});
// it('should have correct length on #valueOf', function(done){
// var result = S().max(5).valueOf();
// should.exist(result);
// (result.length).should.equal(2)
// done();
// })
// })
it('should validate maximum length when max is used', function (done) {
// describe("#_max", function(done){
// it('should validate on known valid input', function(done){
// var inputs = ["abc", "de", ""];
// var validator = S()._max(4);
// for(var i in inputs){
// var currentResult = validator(inputs[i]);
// should.exist(currentResult);
// currentResult.should.equal(true);
// }
// done();
// })
var t = S().max(3);
verifyBehavior(t, [
['test', false],
['0', true],
[null, false]
], done);
});
// it('should invalidate on known invalid inputs', function(done){
// var inputs = ["abcde", "fghij", "klmnopqrstuv"];
// var validator = S()._max(4);
// for(var i in inputs){
// var currentResult = validator(inputs[i]);
// should.exist(currentResult);
// currentResult.should.equal(false);
// }
// done();
// })
// })
it('should validate regex', function (done) {
// describe("#regex", function(done){
// it('should exist', function(done){
// should.exist(S().regex);
// done();
// })
var t = S().regex(/^[0-9][-][a-z]+$/);
verifyBehavior(t, [
['van', false],
['0-www', true]
], done);
});
// it("should have corresponding validator function", function(done){
// should.exist(S()._regex);
// done();
// })
it('should validate alphanum when alphanum allows spaces', function (done) {
// it('should have correct length on #valueOf', function(done){
// var result = S().regex(/^[a-z]+$/).valueOf();
// should.exist(result);
// (result.length).should.equal(2)
// done();
// })
// })
var t = S().alphanum(true);
verifyBehavior(t, [
['w0rld of w4lm4rtl4bs', true],
['abcd#f?h1j orly?', false]
], done);
});
// describe("#_regex", function(done){
// it('should validate on known valid input', function(done){
// var inputs = ["aaaaa", "abcdefghijklmnopqrstuvwxyz", "walmartlabs"];
// var validator = S()._regex(/^[a-z]+$/);
// for(var i in inputs){
// var currentResult = validator(inputs[i]);
// should.exist(currentResult);
// currentResult.should.equal(true);
// }
// done();
// })
it('should validate alphanum when alphanum doesn\'t allow spaces', function (done) {
// it('should invalidate on known invalid inputs', function(done){
// var inputs = ["abcd#f?h1j", "m3ch4", "m3g4"];
// var validator = S()._regex(/^[a-z]+$/);
// for(var i in inputs){
// var currentResult = validator(inputs[i]);
// should.exist(currentResult);
// currentResult.should.equal(false);
// }
// done();
// })
// })
// })
var t = S().alphanum(false);
verifyBehavior(t, [
['w0rld of w4lm4rtl4bs', false],
['w0rldofw4lm4rtl4bs', true],
['abcd#f?h1j orly?', false]
], done);
});
it('should validate email', function (done) {
var t = S().email();
verifyBehavior(t, [
['van@walmartlabs.com', true],
['@iaminvalid.com', false]
], done);
});
it('should validate date', function (done) {
var t = S().date();
verifyBehavior(t, [
['Mon Aug 20 2012 12:14:33 GMT-0700 (PDT)', true],
['2012-08-20T19:14:33.000Z', true],
[null, false],
['worldofwalmartlabs', false]
], done);
});
it('should return false for denied value', function (done) {
var text = S().deny('joi');
var result = text.validate('joi');
expect(result).to.exist;
expect(result).to.equal(false);
done();
});
it('should return true for allowed value', function (done) {
var text = S().allow('hapi');
var result = text.validate('result');
expect(result).to.exist;
expect(result).to.equal(true);
done();
});
it('should validate with one validator (min)', function (done) {
var text = S().min(3);
var result = text.validate('walmart');
expect(result).to.exist;
expect(result).to.equal(true);
done();
});
it('should validate with two validators (min, required)', function (done) {
var text = S().min(3).required();
var result = text.validate('walmart');
expect(result).to.exist;
expect(result).to.equal(true);
var result2 = text.validate();
expect(result2).to.exist;
expect(result2).to.equal(false);
done();
});
it('should validate null with nullOk()', function (done) {
verifyBehavior(S().nullOk(), [
[null, true]
], done);
});
it('should validate "" (empty string) with emptyOk()', function (done) {
verifyBehavior(S().emptyOk(), [
['', true],
['', true]
], done);
});
it('should handle combination of required and min', function (done) {
var rule = S().required().min(3);
verifyBehavior(rule, [
['x', false],
['123', true],
['', false],
[null, false]
], done);
});
it('should handle combination of required and max', function (done) {
var rule = S().required().max(3);
verifyBehavior(rule, [
['x', true],
['123', true],
['1234', false],
['', false],
[null, false]
], done);
});
it('should handle combination of emptyOk and min', function (done) {
var rule = S().emptyOk().min(3);
verifyBehavior(rule, [
['x', false],
['123', true],
['1234', true],
['', true],
[null, false]
], done);
});
it('should handle combination of emptyOk and max', function (done) {
var rule = S().emptyOk().max(3);
verifyBehavior(rule, [
['x', true],
['123', true],
['1234', false],
['', true],
[null, false]
], done);
});
it('should handle combination of min and max', function (done) {
var rule = S().min(2).max(3);
verifyBehavior(rule, [
['x', false],
['123', true],
['1234', false],
['12', true],
['', false],
[null, false]
], done);
});
it('should handle combination of min, max, and emptyOk', function (done) {
var rule = S().min(2).max(3).emptyOk();
verifyBehavior(rule, [
['x', false],
['123', true],
['1234', false],
['12', true],
['', true],
[null, false]
], done);
});
it('should handle combination of min, max, and required', function (done) {
var rule = S().min(2).max(3).required();
verifyBehavior(rule, [
['x', false],
['123', true],
['1234', false],
['12', true],
['', false],
[null, false]
], done);
});
it('should handle combination of min, max, and regex', function (done) {
var rule = S().min(2).max(3).regex(/^a/);
verifyBehavior(rule, [
['x', false],
['123', false],
['1234', false],
['12', false],
['ab', true],
['abc', true],
['abcd', false],
['', false],
[null, false]
], done);
});
it('should handle combination of min, max, regex, and emptyOk', function (done) {
var rule = S().min(2).max(3).regex(/^a/).emptyOk();
verifyBehavior(rule, [
['x', false],
['123', false],
['1234', false],
['12', false],
['ab', true],
['abc', true],
['abcd', false],
['', true],
[null, false]
], done);
});
it('should handle combination of min, max, regex, and required', function (done) {
var rule = S().min(2).max(3).regex(/^a/).required();
verifyBehavior(rule, [
['x', false],
['123', false],
['1234', false],
['12', false],
['ab', true],
['abc', true],
['abcd', false],
['', false],
[null, false]
], done);
});
it('should handle combination of min, max, and alphanum', function (done) {
var rule = S().min(2).max(3).alphanum();
verifyBehavior(rule, [
['x', false],
['123', true],
['1234', false],
['12', true],
['ab', true],
['abc', true],
['abcd', false],
['*ab', false],
['', false],
[null, false]
], done);
});
it('should handle combination of min, max, alphanum, and emptyOk', function (done) {
var rule = S().min(2).max(3).alphanum().emptyOk();
verifyBehavior(rule, [
['x', false],
['123', true],
['1234', false],
['12', true],
['ab', true],
['abc', true],
['abcd', false],
['*ab', false],
['', true],
[null, false]
], done);
});
it('should handle combination of min, max, alphanum, and required', function (done) {
var rule = S().min(2).max(3).alphanum().required();
verifyBehavior(rule, [
['x', false],
['123', true],
['1234', false],
['12', true],
['ab', true],
['abc', true],
['abcd', false],
['*ab', false],
['', false],
[null, false]
], done);
});
it('should handle combination of min, max, alphanum, and regex', function (done) {
var rule = S().min(2).max(3).alphanum().regex(/^a/);
verifyBehavior(rule, [
['x', false],
['123', false],
['1234', false],
['12', false],
['ab', true],
['abc', true],
['a2c', true],
['abcd', false],
['*ab', false],
['', false],
[null, false]
], done);
});
it('should handle combination of min, max, alphanum, required, and regex', function (done) {
var rule = S().min(2).max(3).alphanum().required().regex(/^a/);
verifyBehavior(rule, [
['x', false],
['123', false],
['1234', false],
['12', false],
['ab', true],
['abc', true],
['a2c', true],
['abcd', false],
['*ab', false],
['', false],
[null, false]
], done);
});
it('should handle combination of min, max, alphanum, emptyOk, and regex', function (done) {
var rule = S().min(2).max(3).alphanum().emptyOk().regex(/^a/);
verifyBehavior(rule, [
['x', false],
['123', false],
['1234', false],
['12', false],
['ab', true],
['abc', true],
['a2c', true],
['abcd', false],
['*ab', false],
['', true],
[null, false]
], done);
});
it('should handle combination of min, max, and date', function (done) {
var rule = S().min(2).max(3).date();
verifyBehavior(rule, [
['12', true],
['1-2', true],
['abc', false],
['a2c', false],
['abcd', false],
['*ab', false],
['', false],
[null, false]
], done);
});
it('should handle combination of date and regex', function (done) {
var rule = S().date().regex(/^1/);
verifyBehavior(rule, [
['x', false],
['1-2-1990', true],
['2-2-1990', false],
['', false],
[null, false]
], done);
});
it('should handle combination of date, regex, and min', function (done) {
var rule = S().date().regex(/^1/).min(4);
verifyBehavior(rule, [
['x', false],
['1-2-1990', true],
['1-2', false],
['2-2-1990', false],
['', false],
[null, false]
], done);
});
it('should handle combination of date, regex, and max', function (done) {
var rule = S().date().regex(/^1/).max(4);
verifyBehavior(rule, [
['x', false],
['1-2-1990', false],
['1-2', true],
['2-2-1990', false],
['', false],
[null, false]
], done);
});
it('should handle combination of date, regex, min, and max', function (done) {
var rule = S().date().regex(/^1/).min(3).max(4);
verifyBehavior(rule, [
['x', false],
['1-2-1990', false],
['1-2', true],
['2-2-1990', false],
['', false],
[null, false]
], done);
});
it('should handle combination of date, regex, min, max, and allow', function (done) {
var rule = S().date().regex(/^1/).min(3).max(4).allow('x');
verifyBehavior(rule, [
['x', true],
['1-2-1990', false],
['1-2', true],
['2-2-1990', false],
['', false],
[null, false]
], done);
});
it('should handle combination of date, regex, min, max, allow, and deny', function (done) {
var rule = S().date().regex(/^1/).min(3).max(4).allow('x').deny('1-2');
verifyBehavior(rule, [
['x', true],
['1-2-1990', false],
['1-2', false],
['2-2-1990', false],
['', false],
[null, false]
], done);
});
it('should handle combination of date, regex, min, max, allow, deny, and emptyOk', function (done) {
var rule = S().date().regex(/^1/).min(3).max(4).allow('x').deny('1-2').emptyOk();
verifyBehavior(rule, [
['x', true],
['1-2-1990', false],
['1-2', false],
['2-2-1990', false],
['', true],
[null, false]
], done);
});
it('should handle combination of date, regex, min, max, and emptyOk', function (done) {
var rule = S().date().regex(/^1/).min(3).max(4).emptyOk();
verifyBehavior(rule, [
['x', false],
['1-2-1990', false],
['1-2', true],
['2-2-1990', false],
['', true],
[null, false]
], done);
});
it('should handle combination of date, regex, min, max, and nullOk', function (done) {
var rule = S().date().regex(/^1/).min(3).max(4).nullOk();
verifyBehavior(rule, [
['x', false],
['1-2-1990', false],
['1-2', true],
['2-2-1990', false],
['', false],
[null, true]
], done);
});
it('should handle combination of date, regex, min, max, nullOk, emptyOk', function (done) {
var rule = S().date().regex(/^1/).min(3).max(4).nullOk().emptyOk();
verifyBehavior(rule, [
['x', false],
['1-2-1990', false],
['1-2', true],
['2-2-1990', false],
['', true],
[null, true]
], done);
});
it('should handle combination of date, regex, min, max, and required', function (done) {
var rule = S().date().regex(/^1/).min(3).max(4).required();
verifyBehavior(rule, [
['x', false],
['1-2-1990', false],
['1-2', true],
['2-2-1990', false],
['', false],
[null, false]
], done);
});
it('should handle combination of email and min', function (done) {
var rule = S().email().min(8);
verifyBehavior(rule, [
['x@x.com', false],
['123@x.com', true],
['', false],
[null, false]
], done);
});
it('should handle combination of email, min, and max', function (done) {
var rule = S().email().min(8).max(10);
verifyBehavior(rule, [
['x@x.com', false],
['123@x.com', true],
['1234@x.com', true],
['12345@x.com', false],
['', false],
[null, false]
], done);
});
it('should handle combination of email, min, max, and deny', function (done) {
var rule = S().email().min(8).max(10).deny('123@x.com');
verifyBehavior(rule, [
['x@x.com', false],
['123@x.com', false],
['1234@x.com', true],
['12345@x.com', false],
['', false],
[null, false]
], done);
});
it('should handle combination of email, min, max, and allow', function (done) {
var rule = S().email().min(8).max(10).allow('x@x.com');
verifyBehavior(rule, [
['x@x.com', true],
['123@x.com', true],
['1234@x.com', true],
['12345@x.com', false],
['', false],
[null, false]
], done);
});
it('should handle combination of email, min, max, allow, and deny', function (done) {
var rule = S().email().min(8).max(10).allow('x@x.com').deny('123@x.com');
verifyBehavior(rule, [
['x@x.com', true],
['123@x.com', false],
['1234@x.com', true],
['12345@x.com', false],
['', false],
[null, false]
], done);
});
it('should handle combination of email, min, max, allow, deny, and emptyOk', function (done) {
var rule = S().email().min(8).max(10).allow('x@x.com').deny('123@x.com').emptyOk();
verifyBehavior(rule, [
['x@x.com', true],
['123@x.com', false],
['1234@x.com', true],
['12345@x.com', false],
['', true],
[null, false]
], done);
});
it('should handle combination of email, min, max, allow, and emptyOk', function (done) {
var rule = S().email().min(8).max(10).allow('x@x.com').emptyOk();
verifyBehavior(rule, [
['x@x.com', true],
['123@x.com', true],
['1234@x.com', true],
['12345@x.com', false],
['', true],
[null, false]
], done);
});
it('should handle combination of email, min, max, allow, deny, and regex', function (done) {
var rule = S().email().min(8).max(10).allow('x@x.com').deny('123@x.com').regex(/^1/);
verifyBehavior(rule, [
['x@x.com', true],
['123@x.com', false],
['1234@x.com', true],
['12345@x.com', false],
['', false],
[null, false]
], done);
});
it('should handle combination of email, min, max, allow, deny, regex, and emptyOk', function (done) {
var rule = S().email().min(8).max(10).allow('x@x.com').deny('123@x.com').regex(/^1/).emptyOk();
verifyBehavior(rule, [
['x@x.com', true],
['123@x.com', false],
['1234@x.com', true],
['12345@x.com', false],
['', true],
[null, false]
], done);
});
it('should handle combination of email, min, max, and emptyOk', function (done) {
var rule = S().email().min(8).max(10).emptyOk();
verifyBehavior(rule, [
['x@x.com', false],
['123@x.com', true],
['1234@x.com', true],
['12345@x.com', false],
['', true],
[null, false]
], done);
});
it('should handle combination of email, min, max, and regex', function (done) {
var rule = S().email().min(8).max(10).regex(/^1234/);
verifyBehavior(rule, [
['x@x.com', false],
['123@x.com', false],
['1234@x.com', true],
['12345@x.com', false],
['', false],
[null, false]
], done);
});
it('should handle combination of email, min, max, regex, and emptyOk', function (done) {
var rule = S().email().min(8).max(10).regex(/^1234/).emptyOk();
verifyBehavior(rule, [
['x@x.com', false],
['123@x.com', false],
['1234@x.com', true],
['12345@x.com', false],
['', true],
[null, false]
], done);
});
it('should handle combination of email, min, max, regex, and required', function (done) {
var rule = S().email().min(8).max(10).regex(/^1234/).required();
verifyBehavior(rule, [
['x@x.com', false],
['123@x.com', false],
['1234@x.com', true],
['12345@x.com', false],
['', false],
[null, false]
], done);
});
});
});

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc