Initial upload

This commit is contained in:
Martin Donnelly 2016-03-11 09:49:35 +00:00
commit ae5ef44174
5 changed files with 836 additions and 0 deletions

32
.editorconfig Normal file
View File

@ -0,0 +1,32 @@
; http://editorconfig.org
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
indent_style = space
indent_size = 2
[*.txt]
insert_final_newline = false
trim_trailing_whitespace = false
[*.py]
indent_size = 4
[*.m]
indent_size = 4
[Makefile]
indent_style = tab
indent_size = 8
[*.{js,json}]
indent_style = space
indent_size = 2
[*.md]
trim_trailing_whitespace = false

177
.gitignore vendored Normal file
View File

@ -0,0 +1,177 @@
# Created by .ignore support plugin (hsz.mobi)
### Archives template
# It's better to unpack these files and commit the raw source because
# git has its own built in compression methods.
*.7z
*.jar
*.rar
*.zip
*.gz
*.bzip
*.bz2
*.xz
*.lzma
*.cab
#packing-only formats
*.iso
*.tar
#package management formats
*.dmg
*.xpi
*.gem
*.egg
*.deb
*.rpm
*.msi
*.msm
*.msp
### Windows template
# Windows image file caches
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msm
*.msp
# Windows shortcuts
*.lnk
### OSX template
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
### JetBrains template
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio
*.iml
## Directory-based project format:
.idea/
# if you remove the above rule, at least ignore the following:
# User-specific stuff:
# .idea/workspace.xml
# .idea/tasks.xml
# .idea/dictionaries
# Sensitive or high-churn files:
# .idea/dataSources.ids
# .idea/dataSources.xml
# .idea/sqlDataSources.xml
# .idea/dynamic.xml
# .idea/uiDesigner.xml
# Gradle:
# .idea/gradle.xml
# .idea/libraries
# Mongo Explorer plugin:
# .idea/mongoSettings.xml
## File-based project format:
*.ipr
*.iws
## Plugin-specific files:
# IntelliJ
/out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
### Node template
# Logs
logs
*.log
npm-debug.log*
# Runtime data
pids
*.pid
*.seed
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# node-waf configuration
.lock-wscript
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Dependency directory
# https://docs.npmjs.com/misc/faq#should-i-check-my-node-modules-folder-into-git
node_modules
### VisualStudioCode template
.settings
### Xcode template
# Xcode
#
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
## Build generated
build/
DerivedData
## Various settings
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata
## Other
*.xccheckout
*.moved-aside
*.xcuserstate

268
md-validator.js Normal file
View File

@ -0,0 +1,268 @@
"use strict";
/**
*
* User: Martin Donnelly
* Date: 2016-03-09
* Time: 14:26
*
*/
var VALIDATE = new function() {
this.dateBuilder = function(d, m, y) {
return new Date(Date.UTC(y, m, d, 0, 0, 0));
};
/**
* Check to see if a date is actually a valid date (e.g. FF browser converts 31 Feb to an invalid date)
* @param {number} d
* @param {number} m
* @param {number} y
* @returns {boolean}
*/
this.isDateValid = function(d, m, y) {
var enteredDate = new Date(y, m, d);
/*
if (enteredDate.getFullYear() == y && enteredDate.getMonth() == m && enteredDate.getDate() == d) {
return true;
}
*/
return !!(enteredDate.getFullYear() === y && enteredDate.getMonth() === m && enteredDate.getDate() === d);
};
/**
* Validates emails
* @return {boolean}
*/
this.Email = function(email) {
var flag, b;
/*
if (/^\w+([\+\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(email)) {
flag = true;
}
else
flag = false;
*/
flag = !!/^\w+([\+\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(email);
b = email.split("@");
if (b.length > 2) flag = false;
if (b[0].length == 0) flag = false;
if (email.charAt(0) == '.' || email.charAt(email.length - 1) == '.') flag = false;
return flag;
};
/**
*
* @param inval
* @returns {boolean}
*/
this.time = function(inval) {
var rtrn = false, exp = /^([0-9]|0[0-9]|1[0-9]|2[0-3]):[0-5][0-9]$/;
if (exp.test(inval)) {
rtrn = true;
}
return rtrn;
};
/**
*
* @param inval
* @returns {boolean}
*/
this.money = function(inval) {
"use strict";
var rtrn = '', exp = /^\xA3?\d{1,3}?([,]\d{3}|\d)*?([.]\d{1,2})?$/;
if (exp.test(inval)) {
rtrn = exp.exec(inval);
}
return rtrn[0];
};
/**
* Validates UK postcodes
*/
this.checkPostCode = function(toCheck) {
// Permitted letters depend upon their position in the postcode.
var valid, postCode;
var alpha1 = '[abcdefghijklmnoprstuwyz]'; // Character 1
var alpha2 = '[abcdefghklmnopqrstuvwxy]'; // Character 2
var alpha3 = '[abcdefghjkpmnrstuvwxy]'; // Character 3
var alpha4 = '[abehmnprvwxy]'; // Character 4
var alpha5 = '[abdefghjlnpqrstuwxyz]'; // Character 5
var BFPOa5 = '[abdefghjlnpqrst]'; // BFPO alpha5
var BFPOa6 = '[abdefghjlnpqrstuwzyz]'; // BFPO alpha6
var invalidW1 = /^(W1)([eilmnopqrvwxyz]{1})(\s*)([0-9]{1}[abdefghjlnpqrstuwxyz]{2})$/i;
// Array holds the regular expressions for the valid postcodes
var pcexp = [];
// BFPO postcodes
pcexp.push(new RegExp('^(bf1)(\\s*)([0-6]{1}' + BFPOa5 + '{1}' + BFPOa6 + '{1})$', 'i'));
// Expression for postcodes: AN NAA, ANN NAA, AAN NAA, and AANN NAA
pcexp.push(new RegExp('^(' + alpha1 + '{1}' + alpha2 + '?[0-9]{1,2})(\\s*)([0-9]{1}' + alpha5 + '{2})$', 'i'));
// Expression for postcodes: ANA NAA
pcexp.push(new RegExp('^(' + alpha1 + '{1}[0-9]{1}' + alpha3 + '{1})(\\s*)([0-9]{1}' + alpha5 + '{2})$', 'i'));
// Expression for postcodes: AANA NAA
pcexp.push(new RegExp('^(' + alpha1 + '{1}' + alpha2 + '{1}' + '?[0-9]{1}' + alpha4 + '{1})(\\s*)([0-9]{1}' + alpha5 + '{2})$', 'i'));
// Exception for the special postcode GIR 0AA
pcexp.push(/^(GIR)(\s*)(0AA)$/i);
// Standard BFPO numbers
pcexp.push(/^(bfpo)(\s*)([0-9]{1,4})$/i);
// c/o BFPO numbers
pcexp.push(/^(bfpo)(\s*)(c\/o\s*[0-9]{1,3})$/i);
// Overseas Territories
pcexp.push(/^([A-Z]{4})(\s*)(1ZZ)$/i);
// Anguilla
pcexp.push(/^(ai-2640)$/i);
// Load up the string to check
postCode = toCheck;
// Assume we're not going to find a valid postcode
valid = false;
// Check the string against the types of post codes
for (var i = 0; i < pcexp.length; i++) {
if (pcexp[i].test(postCode)) {
// The post code is valid - split the post code into component parts
pcexp[i].exec(postCode);
// Copy it back into the original string, converting it to uppercase
// and inserting a space between the inward and outward codes
postCode = RegExp.$1.toUpperCase() + ' ' + RegExp.$3.toUpperCase();
// If it is a BFPO c/o type postcode, tidy up the "c/o" part
postCode = postCode.replace(/C\/O\s*/, 'c/o ');
// If it is the Anguilla overseas territory postcode, we need to
// treat it specially
if (toCheck.toUpperCase() == 'AI-2640') {postCode = 'AI-2640'}
// Load new postcode back into the form element
valid = true;
// Remember that we have found that the code is valid and break
// from loop
break;
}
}
if (invalidW1.test(postCode)) {
valid = false;
}
// Return with either the reformatted valid postcode or the original
// invalid postcode
//if (valid) {return postCode;} else return false;
if (valid) {return postCode;}
else return '';
};
/**
* Validates UK Telephone numbers
* @param {string} telephoneNumber
* @returns {*}
*/
this.checkUKTelephone = function(telephoneNumber) {
// Convert into a string and check that we were provided with something
var telNumberErrorNo, telnum = telephoneNumber + ' ';
if (telnum.length == 1) {
// telNumberErrorNo = 1;
return false;
}
telnum = (telnum).trim();
// Don't allow country codes to be included (assumes a leading "+")
var exp = /^(\+)[\s]*(.*)$/;
if (exp.test(telnum) == true) {
//telNumberErrorNo = 2;
return false;
}
// Remove spaces from the telephone number to help validation
while (telnum.indexOf(' ') != -1) {
telnum = telnum.slice(0,
telnum.indexOf(' ')) + telnum.slice(telnum.indexOf(' ') + 1);
}
// Remove hyphens from the telephone number to help validation
while (telnum.indexOf('-') != -1) {
telnum = telnum.slice(0,
telnum.indexOf('-')) + telnum.slice(telnum.indexOf('-') + 1);
}
// Now check that all the characters are digits
exp = /^[0-9]{10,11}$/;
if (exp.test(telnum) != true) {
// telNumberErrorNo = 3;
return false;
}
// Now check that the first digit is 0
exp = /^0[0-9]{9,10}$/;
if (exp.test(telnum) != true) {
// telNumberErrorNo = 4;
return false;
}
// Disallow numbers allocated for dramas.
// Array holds the regular expressions for the drama telephone numbers
var tnexp = [];
tnexp.push(
/^(0113|0114|0115|0116|0117|0118|0121|0131|0141|0151|0161)(4960)[0-9]{3}$/);
tnexp.push(/^02079460[0-9]{3}$/);
tnexp.push(/^01914980[0-9]{3}$/);
tnexp.push(/^02890180[0-9]{3}$/);
tnexp.push(/^02920180[0-9]{3}$/);
tnexp.push(/^01632960[0-9]{3}$/);
tnexp.push(/^07700900[0-9]{3}$/);
tnexp.push(/^08081570[0-9]{3}$/);
tnexp.push(/^09098790[0-9]{3}$/);
tnexp.push(/^03069990[0-9]{3}$/);
for (var i = 0; i < tnexp.length; i++) {
if (tnexp[i].test(telnum)) {
telNumberErrorNo = 5;
return false;
}
}
// Finally check that the telephone number is appropriate.
exp = (/^(01|02|03|05|070|071|072|073|074|075|07624|077|078|079)[0-9]+$/);
if (exp.test(telnum) != true) {
// telNumberErrorNo = 5;
return false;
}
// Telephone number seems to be valid - return the stripped telehone number
return telnum;
};
};
module.exports = VALIDATE;

25
package.json Normal file
View File

@ -0,0 +1,25 @@
{
"name": "node-validator",
"version": "0.0.1",
"description": "A collection of validators.",
"main": "md-validator.js",
"scripts": {
"test": "mocha --recursive --reporter spec --bail --check-leaks --timeout 3000"
},
"repository": {
"type": "git",
"url": "git+http://gitlab.silvrtree.co.uk/martind2000/node-validator.git"
},
"keywords": [
"validator"
],
"engines": {
"node": "*"
},
"author": "Martin Donnelly <martind2000@gmail.com>",
"license": "ISC",
"private": true,
"devDependencies": {
"mocha": "^2.4.5"
}
}

334
test/md-validator.js Normal file
View File

@ -0,0 +1,334 @@
/**
*
* User: Martin Donnelly
* Date: 2016-03-09
* Time: 14:37
*
*/
"use strict";
var mdValidate = require('../md-validator');
var assert = require('assert');
var phone = [
'A',
'AA',
'AAA',
'AAAA',
'AAAAA',
'AAAAAA',
'0',
'01',
'012',
'0123',
'01234',
'012345',
'0123456',
'01234567',
'012345678',
'01134960000',
'01134960500',
'01134960999',
'01144960000',
'01144960500',
'01144960999',
'01154960000',
'01154960500',
'01154960999',
'01164960000',
'01164960500',
'01164960999',
'01174960000',
'01174960500',
'01174960999',
'01184960000',
'01184960500',
'01184960999',
'01214960000',
'01214960500',
'01214960999',
'01314960000',
'01314960500',
'01314960999',
'01414960000',
'01414960500',
'01414960999',
'01514960000',
'01514960500',
'01514960999',
'01614960000',
'01614960500',
'01614960999',
'02079460000',
'02079460500',
'02079460999',
'01914980000',
'01914980500',
'01914980999',
'02890180000',
'02890180500',
'02890180999',
'02920180000',
'02920180500',
'02920180999',
'01632960000',
'01632960500',
'01632960999',
'07700900000',
'07700900500',
'07700900999',
'08081570000',
'08081570555',
'08081570999',
'09098790000',
'09098790500',
'09098790999',
'03069990000',
'03069990500',
'03069990999',
'08002323636',
'09002323636',
'06002323636',
"00254745856",
"+254745856"
];
var validPhone = ['01389703002', '07944577934', '01412807000', '02071539996'];
var postcodes = [
'A',
'AA',
'AAA',
'AAAA',
'AAAAA',
'AAAAAA',
'Q1 1AA',
'V1 1AA',
'X1 1AA',
'M1 CAA',
'M1 IAA',
'M1 KAA',
'M1 MAA',
'M1 OAA',
'M1 VAA',
'Q60 1NW',
'V60 1NW',
'X60 1NW',
'M60 1CW',
'M60 1IW',
'M60 1KW',
'M60 1MW',
'M60 1OW',
'M60 1VW',
'M60 1NC',
'M60 1NI',
'M60 1NK',
'M60 1NM',
'M60 1NO',
'M60 1NV',
'QR2 6XH',
'VR2 6XH',
'XR2 6XH',
'CI2 6XH',
'CJ2 6XH',
'CZ2 6XH',
'CR2 6CH',
'CR2 6IH',
'CR2 6KH',
'CR2 6MH',
'CR2 6OH',
'CR2 6VH',
'CR2 6XC',
'CR2 6XI',
'CR2 6XK',
'CR2 6XM',
'CR2 6XO',
'CR2 6XV',
'QN55 1PT',
'VN55 1PT',
'XN55 1PT',
'DI55 1PT',
'DJ55 1PT',
'DZ55 1PT',
'DN55 1CT',
'DN55 1IT',
'DN55 1KT',
'DN55 1MT',
'DN55 1OT',
'DN55 1VT',
'DN55 1PC',
'DN55 1PI',
'DN55 1PK',
'DN55 1PM',
'DN55 1PO',
'DN55 1PV',
'Q1A 1HQ',
'V1A 1HQ',
'X1A 1HQ',
'W1I 1HQ',
'W1L 1HQ',
'W1M 1HQ',
'W1N 1HQ',
'W1O 1HQ',
'W1P 1HQ',
'W1Q 1HQ',
'W1R 1HQ',
'W1V 1HQ',
'W1X 1HQ',
'W1Y 1HQ',
'W1Z 1HQ',
'W1A 1CQ',
'W1A 1IQ',
'W1A 1KQ',
'W1A 1MQ',
'W1A 1OQ',
'W1A 1VQ',
'W1A 1HC',
'W1A 1HI',
'W1A 1HK',
'W1A 1HM',
'W1A 1HO',
'W1A 1HV',
'QC1A 1BB',
'VC1A 1BB',
'XC1A 1BB',
'EI1A 1BB',
'EJ1A 1BB',
'EZ1A 1BB',
'EC1C 1BB',
'EC1D 1BB',
'EC1F 1BB',
'EC1G 1BB',
'EC1I 1BB',
'EC1J 1BB',
'EC1K 1BB',
'EC1L 1BB',
'EC1O 1BB',
'EC1Q 1BB',
'EC1S 1BB',
'EC1T 1BB',
'EC1U 1BB',
'EC1Z 1BB',
'EC1A 1IB',
'EC1A 1MB',
'EC1A 1OB',
'EC1A 1VB',
'EC1A 1BC',
'EC1A 1BI',
'EC1A 1BK',
'EC1A 1BM',
'EC1A 1BO',
'EC1A 1BV'
];
var validPostcodes = [
'M1 1AA',
'M60 1NW',
'CR2 6XH',
'DN55 1PT',
'W1A 1HQ',
'EC1A 1BB',
'BT9 7JL',
'GIR 0AA'
];
// taken from http://blogs.msdn.com/b/testing123/archive/2009/02/05/email-address-test-cases.aspx
// having difficulty invalidating /*'あいうえお@domain.com',*/
// Several test cases for the email address have been removed as they should really be fixed by the mail system
// and they would be costly to fix in code at the moment
var invalidEmail = [
'plainaddress',
'#@%^%#$@#$@#.com',
'@domain.com',
'Joe Smith <email@domain.com>',
'email.domain.com',
'email@domain@domain.com',
'.email@domain.com',
'email.@domain.com',
'email..email@domain.com',
'email@domain.com (Joe Smith)',
'email@domain',
'email@-domain.com',
/*'email@domain.web',*/
'email@111.222.333.44444',
'email@domain..com'
];
var validEmail = [
'email@domain.com',
'firstname.lastname@domain.com',
'email@subdomain.domain.com',
'firstname+lastname@domain.com',
'email@123.123.123.123',
/*'email@[123.123.123.123]',*/
/*'"email"@domain.com',*/
'1234567890@domain.com',
'email@domain-one.com',
'_______@domain.com',
/*'email@domain.name',*/
'email@domain.co.uk',
'firstname-lastname@domain.com'
];
var emailOne = ['m@g.com', 'm@g.co.uk', 'bob@g.com'];
var emailTwo = ['m@g.co.uk', 'bob@g.com', 'm@g.com'];
describe('MD-Validator', function() {
it('should not validate an incorrect email address', function(done) {
for (var i in invalidEmail) {
assert.ifError(mdValidate.Email(invalidEmail[i]));
}
done();
});
it('should validate a correct email address', function(done) {
for (var i in validEmail) {
assert(mdValidate.Email(validEmail[i]));
}
done();
});
it('should not validate an incorrect phone number', function(done) {
for (var i in phone) {
assert.ifError(mdValidate.checkUKTelephone(phone[i]));
}
done();
});
it('should validate a correct phone number', function(done) {
for (var i in validPhone) {
assert(mdValidate.checkUKTelephone(validPhone[i]));
}
done();
});
it('should not validate an incorrect postcode', function(done) {
for (var i in postcodes) {
assert.ifError(mdValidate.checkPostCode(postcodes[i]));
}
done();
});
it('should validate a correct postcode', function(done) {
for (var i in validPostcodes) {
assert(mdValidate.checkPostCode(validPostcodes[i]));
}
done();
});
});