Skip to content

Instantly share code, notes, and snippets.

@davidDuymelinck
Last active August 29, 2015 14:11
Show Gist options
  • Save davidDuymelinck/6d73416d44aa0d670b07 to your computer and use it in GitHub Desktop.
Save davidDuymelinck/6d73416d44aa0d670b07 to your computer and use it in GitHub Desktop.
ES6 head first
{
"name": "livevalidation-es6",
"version": "0.0.0",
"description": "es6 version of livevalidation",
"main": "index.js",
"scripts": {
"test": "node_modules/.bin/6to5 src -d test/out && node_modules/.bin/6to5 test-es6 -d test && mocha"
},
"author": "",
"license": "ISC",
"devDependencies": {
"should": "^4.4.1",
"mocha": "^2.0.1",
"6to5": "^1.15.0"
}
}
static fail(errorMessage) {
throw new Validate.Error(errorMessage);
}
static Error(errorMessage) {
this.message = errorMessage;
this.name = 'ValidationError';
}
Numericality: function(value, paramsObj){
var suppliedValue = value;
var value = Number(value);
var paramsObj = paramsObj || {};
var minimum = ((paramsObj.minimum) || (paramsObj.minimum == 0)) ? paramsObj.minimum : null;;
var maximum = ((paramsObj.maximum) || (paramsObj.maximum == 0)) ? paramsObj.maximum : null;
var is = ((paramsObj.is) || (paramsObj.is == 0)) ? paramsObj.is : null;
var notANumberMessage = paramsObj.notANumberMessage || "Must be a number!";
var notAnIntegerMessage = paramsObj.notAnIntegerMessage || "Must be an integer!";
var wrongNumberMessage = paramsObj.wrongNumberMessage || "Must be " + is + "!";
var tooLowMessage = paramsObj.tooLowMessage || "Must not be less than " + minimum + "!";
var tooHighMessage = paramsObj.tooHighMessage || "Must not be more than " + maximum + "!";
if (!isFinite(value)) Validate.fail(notANumberMessage);
if (paramsObj.onlyInteger && (/\.0+$|\.$/.test(String(suppliedValue)) || value != parseInt(value)) ) Validate.fail(notAnIntegerMessage);
switch(true){
case (is !== null):
if( value != Number(is) ) Validate.fail(wrongNumberMessage);
break;
case (minimum !== null && maximum !== null):
Validate.Numericality(value, {tooLowMessage: tooLowMessage, minimum: minimum});
Validate.Numericality(value, {tooHighMessage: tooHighMessage, maximum: maximum});
break;
case (minimum !== null):
if( value < Number(minimum) ) Validate.fail(tooLowMessage);
break;
case (maximum !== null):
if( value > Number(maximum) ) Validate.fail(tooHighMessage);
break;
}
return true;
}
describe('Numericality', () => {
it('should be true', () => {
validate.Numericality(2).should.be.true;
validate.Numericality('2').should.be.true;
validate.Numericality(0).should.be.true;
validate.Numericality(-2).should.be.true;
validate.Numericality(2.5).should.be.true;
validate.Numericality(2, validate.NumericalityConfig({isInteger: true})).should.be.true;
validate.Numericality(1.123e3, validate.NumericalityConfig({isInteger: true})).should.be.true;
validate.Numericality('1.123e3', validate.NumericalityConfig({isInteger: true})).should.be.true;
validate.Numericality(0, validate.NumericalityConfig({isInteger: true})).should.be.true;
validate.Numericality(9, validate.NumericalityConfig({exactNr : 9})).should.be.true;
validate.Numericality(9, validate.NumericalityConfig({minimum: 9})).should.be.true;
validate.Numericality(10, validate.NumericalityConfig({minimum: 9})).should.be.true;
validate.Numericality(9, validate.NumericalityConfig({maximum: 10})).should.be.true;
validate.Numericality(10, validate.NumericalityConfig({maximum: 10})).should.be.true;
validate.Numericality(9, validate.NumericalityConfig({minimum: 9, maximum: 10})).should.be.true;
validate.Numericality(10, validate.NumericalityConfig({minimum: 9, maximum: 10})).should.be.true;
})
it('should return a number error', () => {
try{
validate.Numericality('a').should.be.an.instanceof(validate.Error);
}catch(err){
err.name.should.equal('ValidationError');
err.message.should.eql('Must be a number!');
}
})
it('should return a custom number error', () => {
try{
validate.Numericality('a', validate.NumericalityConfig({notNrErrMsg: 'Not a number!'})).should.be.an.instanceof(validate.Error);
}catch(err){
err.message.should.eql('Not a number!');
}
})
it('should return an integer error', () => {
try{
validate.Numericality(1.5, validate.NumericalityConfig({isInteger: true})).should.be.an.instanceof(validate.Error);
}catch(err){
err.message.should.eql('Must be an integer!');
}
})
it('should return a custom integer error', () => {
try{
validate.Numericality(1.5, validate.NumericalityConfig({isInteger: true, notIntErrMsg: 'Not an integer!'})).should.be.an.instanceof(validate.Error);
}catch(err){
err.message.should.eql('Not an integer!');
}
})
it('should return an exact number error', () => {
try{
validate.Numericality(1.5, validate.NumericalityConfig({exactNr: 1})).should.be.an.instanceof(validate.Error);
}catch(err){
err.message.should.eql('Must be 1!');
}
})
it('should return a custom exact number error', () => {
try{
validate.Numericality(1.5, validate.NumericalityConfig({exactNr: 1, wrongNrErrMsg: (exact) => `The number must be ${exact}!`})).should.be.an.instanceof(validate.Error);
}catch(err){
err.message.should.eql('The number must be 1!');
}
})
it('should return a minimum error', () => {
try{
validate.Numericality(1.5, validate.NumericalityConfig({minimum: 2})).should.be.an.instanceof(validate.Error);
}catch(err){
err.message.should.eql('Must not be less than 2!');
}
})
it('should return a custom minimum error', () => {
try{
validate.Numericality(1.5, validate.NumericalityConfig({minimum: 2, tooLowErrMsg: (min) => `${min} or higher!`})).should.be.an.instanceof(validate.Error);
}catch(err){
err.message.should.eql('2 or higher!');
}
})
it('should return a maximum error', () => {
try{
validate.Numericality(1.5, validate.NumericalityConfig({maximum: 1})).should.be.an.instanceof(validate.Error);
}catch(err){
err.message.should.eql('Must not be more than 1!');
}
})
it('should return a custom maximum error', () => {
try{
validate.Numericality(1.5, validate.NumericalityConfig({maximum: 1, tooHighErrMsg: (max) => `${max} or lower!`})).should.be.an.instanceof(validate.Error);
}catch(err){
err.message.should.eql('1 or lower!');
}
})
it('should return a range error', () => {
try{
validate.Numericality(1.5, validate.NumericalityConfig({minimum: 1, maximum: 1})).should.be.an.instanceof(validate.Error);
}catch(err){
err.message.should.eql('Must be not less than 1 and not more than 1!');
}
})
it('should return a custom range error', () => {
try{
validate.Numericality(1.5, validate.NumericalityConfig({minimum: 1, maximum: 1, notInRangeErrMsg: (min, max) => `Must be in the ${min}-${max} range!`})).should.be.an.instanceof(validate.Error);
}catch(err){
err.message.should.eql('Must be in the 1-1 range!');
}
})
});
static NumericalityConfig(config = null) {
var defaults = { notNrErrMsg: "Must be a number!",
isInteger: false, notIntErrMsg: "Must be an integer!",
minimum: null, tooLowErrMsg: (min) => `Must not be less than ${min}!`,
maximum: null, tooHighErrMsg: (max) => `Must not be more than ${max}!`,
notInRangeErrMsg: (min, max) => `Must be not less than ${min} and not more than ${max}!`,
exactNr: null, wrongNrErrMsg: (exact) => `Must be ${exact}!`
};
return Validate.mergeObj(defaults, config);
}
static Numericality(value, paramsObj = { notNrErrMsg: "Must be a number!",
isInteger: false, notIntErrMsg: "Must be an integer!",
minimum: null, tooLowErrMsg: (min) => `Must not be less than ${min}!`,
maximum: null, tooHighErrMsg: (max) => `Must not be more than ${max}!`,
notInRangeErrMsg: (min, max) => `Must be not less than ${min} and not more than ${max}!`,
exactNr: null, wrongNrErrMsg: (exact) => `Must be ${exact}!`
}) {
var val = Number(value);
if(isNaN(val)){ Validate.fail(paramsObj.notNrErrMsg); }
if (paramsObj.isInteger && (/\.0+$|\.$/.test(String(value)) || val != parseInt(val)) ){ Validate.fail(paramsObj.notIntErrMsg); }
if(paramsObj.exactNr){
var exactNr = Number(paramsObj.exactNr);
if(isNaN(exactNr)){ throw Error('exactNr is not a number!'); }
if(val !== exactNr){ Validate.fail(paramsObj.wrongNrErrMsg(paramsObj.exactNr)); }
}
if(paramsObj.minimum && paramsObj.maximum){
let minimum = Number(paramsObj.minimum);
let maximum = Number(paramsObj.maximum);
if(isNaN(minimum)){ throw Error('minimum is not a number!'); }
if(isNaN(maximum)){ throw Error('maximum is not a number!'); }
if(val < minimum || val > maximum){ Validate.fail(paramsObj.notInRangeErrMsg(minimum, maximum)); }
}
if(paramsObj.minimum){
let minimum = Number(paramsObj.minimum);
if(isNaN(minimum)){ throw Error('minimum is not a number!'); }
if(val < minimum){ Validate.fail(paramsObj.tooLowErrMsg(minimum)); }
}
if(paramsObj.maximum){
let maximum = Number(paramsObj.maximum);
if(isNaN(maximum)){ throw Error('maximum is not a number!'); }
if(val > maximum){ Validate.fail(paramsObj.tooHighErrMsg(maximum)); }
}
return true;
}
var Validate = {
Presence: function(value, paramsObj){
var paramsObj = paramsObj || {};
var message = paramsObj.failureMessage || "Can't be empty!";
if(value === '' || value === null || value === undefined) Validate.fail(message);
return true;
}
}
import validate from '../test/out/validate';
var should = require('should');
describe('Validate', () => {
describe('Presence', () => {
it('should return true', () => {
validate.Presence('test').should.be.true;
})
it('should return error', () => {
try{
validate.Presence('').should.be.an.instanceof(validate.Error);
}catch(err){
err.name.should.equal('ValidationError');
err.message.should.eql("Can't be empty!")
}
})
it('should return custom error', () => {
try{
validate.Presence('', { errMsg: 'Add a value'}).should.be.an.instanceof(validate.Error);
}catch(err){
err.message.should.eql("Add a value")
}
})
})
// other tests ...
});
class Validate {
static Presence(value, paramsObj = { errMsg: "Can't be empty!"}) {
if(value === '' || value === null || value === undefined){ Validate.fail(paramsObj.errMsg); }
return true;
}
// other methods ...
}
export default Validate
class Validate {
static Presence(value, paramsObj = { errMsg: "Can't be empty!"}) {
if(value === '' || value === null || value === undefined){ Validate.fail(paramsObj.errMsg); }
return true;
}
static NumericalityConfig(config = null) {
var defaults = { notNrErrMsg: "Must be a number!",
isInteger: false, notIntErrMsg: "Must be an integer!",
minimum: null, tooLowErrMsg: (min) => `Must not be less than ${min}!`,
maximum: null, tooHighErrMsg: (max) => `Must not be more than ${max}!`,
notInRangeErrMsg: (min, max) => `Must be not less than ${min} and not more than ${max}!`,
exactNr: null, wrongNrErrMsg: (exact) => `Must be ${exact}!`
};
return Validate.mergeObj(defaults, config);
}
static Numericality(value, paramsObj = { notNrErrMsg: "Must be a number!",
isInteger: false, notIntErrMsg: "Must be an integer!",
minimum: null, tooLowErrMsg: (min) => `Must not be less than ${min}!`,
maximum: null, tooHighErrMsg: (max) => `Must not be more than ${max}!`,
notInRangeErrMsg: (min, max) => `Must be not less than ${min} and not more than ${max}!`,
exactNr: null, wrongNrErrMsg: (exact) => `Must be ${exact}!`
}) {
var val = Number(value);
if(isNaN(val)){ Validate.fail(paramsObj.notNrErrMsg); }
if (paramsObj.isInteger && (/\.0+$|\.$/.test(String(value)) || val != parseInt(val)) ){ Validate.fail(paramsObj.notIntErrMsg); }
Validate.Length(value, Validate.LengthConfig(paramsObj));
return true;
}
static FormatConfig(config = null){
var defaults = {errMsg: "Not valid!", pattern: /./, negate: false};
return Validate.mergeObj(defaults, config);
}
static Format(value, paramsObj = {errMsg: "Not valid!", pattern: /./, negate: false}) {
var value = String(value);
if(!negate && !pattern.test(value)) Validate.fail(message);
if(negate && pattern.test(value)) Validate.fail(message);
return true;
}
static Email(value, paramsObj = {errMsg: "Must be a valid email address!"}) {
Validate.Format(value, { errMsg: message, pattern: /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i } );
return true;
}
static LengthConfig(config = null){
var defaults = {minimum: null, tooLowErrMsg: (min) => `Must not be less than ${min} characters!`,
maximum: null, tooHighErrMsg: (max) => `Must not be more than ${max} characters!`,
notInRangeErrMsg: (min, max) => `Must be not less than ${min} and not more than ${max} characters!`,
exactNr: null, wrongNrErrMsg: (exact) => `Must be ${exact} characters!`};
return Validate.mergeObj(defaults, config);
}
static Length(value, paramsObj = {minimum: null, tooLowErrMsg: (min) => `Must not be less than ${min} characters!`,
maximum: null, tooHighErrMsg: (max) => `Must not be more than ${max} characters!`,
notInRangeErrMsg: (min, max) => `Must be not less than ${min} and not more than ${max} characters!`,
exactNr: null, wrongNrErrMsg: (exact) => `Must be ${exact} characters!`}) {
if(!paramsObj.exactNr && !paramsObj.minimum && !paramsObj.maximum){
throw Error('Validate::Length - At least one value to check against must be added!');
}
if(paramsObj.exactNr){
var exactNr = Number(paramsObj.exactNr);
if(isNaN(exactNr)){ throw Error('Validate::Length - exactNr is not a number!'); }
if(val !== exactNr){ Validate.fail(paramsObj.wrongNrErrMsg(paramsObj.exactNr)); }
}
if(paramsObj.minimum && paramsObj.maximum){
let minimum = Number(paramsObj.minimum);
let maximum = Number(paramsObj.maximum);
if(isNaN(minimum)){ throw Error('Validate::Length - minimum is not a number!'); }
if(isNaN(maximum)){ throw Error('Validate::Length - maximum is not a number!'); }
if(val < minimum || val > maximum){ Validate.fail(paramsObj.notInRangeErrMsg(minimum, maximum)); }
}
if(paramsObj.minimum){
let minimum = Number(paramsObj.minimum);
if(isNaN(minimum)){ throw Error('Validate::Length - minimum is not a number!'); }
if(val < minimum){ Validate.fail(paramsObj.tooLowErrMsg(minimum)); }
}
if(paramsObj.maximum){
let maximum = Number(paramsObj.maximum);
if(isNaN(maximum)){ throw Error('Validate::Length - maximum is not a number!'); }
if(val > maximum){ Validate.fail(paramsObj.tooHighErrMsg(maximum)); }
}
return true;
}
static InclusionConfig(config = null){
var defaults = {errMsg: "Must be included in the list!",
caseSentitive: true, allowNull: false,
partialMatch: false, negate: false,
within: []};
return Validate.mergeObj(defaults, config);
}
static Inclusion(value, paramsObj = {errMsg: "Must be included in the list!",
caseSentitive: true, allowNull: false,
partialMatch: false, negate: false,
within: []}) {
if(paramsObj.allowNull && value == null){ return true; }
if(!paramsObj.allowNull && value == null){ Validate.fail(paramsObj.errMsg); }
if(within.length === 0){ throw new Error('Validate::Inclusion - The within array must have values to check against!'); }
var within = paramsObj.within;
if(!paramsObj.caseSensitive){
for(var j = 0, length = paramsObj.within.length; j < length; ++j){
var item = paramsObj.within[j];
if(typeof item == 'string'){ item = item.toLowerCase(); }
within[j] = item;
}
if(typeof value == 'string'){ value = value.toLowerCase(); }
}
var found = false;
for(var i = 0, length = within.length; i < length; ++i){
if(within[i] == value){ found = true; }
if(paramsObj.partialMatch && value.indexOf(within[i]) != -1){ found = true; }
}
if( (!paramsObj.negate && !found) || (paramsObj.negate && found) ){ Validate.fail(paramsObj.errMsg); }
return true;
}
static ConfirmationConfig(config = null){
var defaults = {errMsg: "Does not match!", match: null};
return Validate.mergeObj(defaults, config);
}
static Confirmation(value, paramsObj = {errMsg: "Does not match!", match: null}) {
if(!paramsObj.match){ throw new Error("Validate::Confirmation - Error validating confirmation: Id of element to match must be provided!"); }
var match = paramsObj.match.nodeName ? paramsObj.match : document.getElementById(paramsObj.match);
if(!match){ throw new Error(`Validate::Confirmation - There is no reference with name of, or element with id of ${paramsObj.match}!`); }
if(value != match.value){ Validate.fail(paramsObj.errMsg); }
return true;
}
static Acceptance(value, paramsObj = {errMsg: "Must be accepted!"}) {
if(!value){ Validate.fail(paramsObj.errMsg); }
return true;
}
static CustomConfig(config = null){
var defaults = {errMsg: "Not valid!", against: function(){ return true; }, args: {}};
return Validate.mergeObj(defaults, config);
}
static Custom(value, paramsObj = {errMsg: "Not valid!", against: function(){ return true; }, args: {}}) {
if(!against(value, args)){ Validate.fail(paramsObj.errMsg); }
return true;
}
static now(validationFunction, value, validationParamsObj = {}) {
if(!validationFunction){ throw new Error("Validate::now - Validation function must be provided!"); }
var isValid = true;
try{
validationFunction(value, validationParamsObj);
} catch(error) {
if(error instanceof Validate.Error){
isValid = false;
}else{
throw error;
}
}finally{
return isValid
}
}
static mergeObj(out, replacements = null){
if(!replacements){ return out; }
for(let attr in out){
if(replacements.hasOwnProperty(attr)){
out[attr] = replacements[attr];
}
}
return out;
}
static fail(errorMessage) {
throw new Validate.Error(errorMessage);
}
static Error(errorMessage) {
this.message = errorMessage;
this.name = 'ValidationError';
}
}
export default Validate;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment