Skip to content

Commit

Permalink
feat: add password
Browse files Browse the repository at this point in the history
Fixes #2
  • Loading branch information
fengmk2 committed Jan 8, 2015
1 parent c46ff79 commit ee5b4f3
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 23 deletions.
16 changes: 16 additions & 0 deletions README.md
Expand Up @@ -115,6 +115,20 @@ If type is `string`, there has four addition rules:
- `max` - The maximum length of the string.
- `min` - The minimum length of the string.

#### email

The `email` type want to match [RFC 5322](http://tools.ietf.org/html/rfc5322#section-3.4) email address.

- `allowEmpty` - allow empty string, default is false.

#### password

The `password` type want to match `/^$/` type string.

- `compare` - Compare field to check equal, default null, not check.
- `max` - The maximum length of the password.
- `min` - The minimum length of the password, default is 6.

#### enum

If type is `enum`, it requires an addition rule:
Expand Down Expand Up @@ -145,6 +159,8 @@ If type is `array`, there has tow addition rule:
- `'boolean'` => `{type: 'boolean', required: true}`
- `'bool'` => `{type: 'bool', required: true}`
- `'string'` => `{type: 'string', required: true, allowEmpty: false}`
- `'email'` => `{type: 'email', required: true, allowEmpty: false, format: EMAIL_RE}`
- `'password'` => `{type: 'password', required: true, allowEmpty: false, format: PASSWORD_RE, min: 6}`
- `'object'` => `{type: 'object', required: true}`
- `'array'` => `{type: 'array', required: true}`
- `[1, 2]` => `{type: 'enum', values: [1, 2]}`
Expand Down
44 changes: 25 additions & 19 deletions benchmark.js
Expand Up @@ -31,6 +31,8 @@ var data = {
sid3: 'foo',
unit: 'y',
email: 'fengmk2@gmail.com',
password: '!@#123',
're-password': '!@#123',
};

var rules = [
Expand All @@ -57,7 +59,9 @@ var rules = [
{ unit: { type: 'enum', values: ['y', 'm', 'd', 'w'] } },
{ unit: ['yy', 'mm', 'dd', 'ww'] },

{ email: 'email' }
{ email: 'email' },

{ password: { type: 'password', compare: 're-password' } },
];

function json(obj) {
Expand All @@ -83,23 +87,25 @@ suite.on('cycle', function(event) {

// $ node benchmark.js
//
// node version: v0.11.14, date: Thu Jan 08 2015 15:31:08 GMT+0800 (CST)
// node version: v0.11.14, date: Thu Jan 08 2015 19:40:04 GMT+0800 (CST)
// Starting...
// 16 tests completed.
// 18 tests completed.
//
// verify {"id":"id"} x 2,115,641 ops/sec ±1.10% (91 runs sampled)
// verify {"id":{"type":"id"}} x 2,089,624 ops/sec ±2.24% (92 runs sampled)
// verify {"date":"date"} x 1,784,996 ops/sec ±6.12% (83 runs sampled)
// verify {"date":{"type":"date"}} x 1,809,219 ops/sec ±3.81% (85 runs sampled)
// verify {"time":"datetime"}:
// verify {"time":{"type":"datetime"}}:
// verify {"age":"number"} x 2,705,620 ops/sec ±1.74% (88 runs sampled)
// verify {"age":{"type":"number"}} x 2,575,615 ops/sec ±2.33% (85 runs sampled)
// verify {"nick":"string"} x 2,140,266 ops/sec ±2.38% (85 runs sampled)
// verify {"nick":{"type":"string"}} x 2,149,018 ops/sec ±2.57% (87 runs sampled)
// verify {"not_exists":"string","required":false} x 927,337 ops/sec ±6.10% (82 runs sampled)
// verify {"sid1":{}} x 1,179,423 ops/sec ±5.53% (76 runs sampled)
// verify {"sid2":{"type":"string","format":{}}} x 1,781,882 ops/sec ±2.90% (86 runs sampled)
// verify {"unit":["y","m","d","w"]} x 2,476,129 ops/sec ±1.48% (90 runs sampled)
// verify {"unit":{"type":"enum","values":["y","m","d","w"]}} x 3,617,270 ops/sec ±2.90% (85 runs sampled)
// verify {"unit":["yy","mm","dd","ww"]} x 1,122,732 ops/sec ±4.24% (85 runs sampled)
// verify {"id":"id"} x 1,896,293 ops/sec ±5.38% (82 runs sampled)
// verify {"id":{"type":"id"}} x 1,473,771 ops/sec ±11.77% (65 runs sampled)
// verify {"date":"date"} x 1,513,462 ops/sec ±9.23% (73 runs sampled)
// verify {"date":{"type":"date"}} x 1,563,038 ops/sec ±8.09% (76 runs sampled)
// verify {"time":"datetime"} x 1,541,142 ops/sec ±6.58% (78 runs sampled)
// verify {"time":{"type":"datetime"}} x 1,735,154 ops/sec ±2.08% (87 runs sampled)
// verify {"age":"number"} x 2,436,145 ops/sec ±5.15% (85 runs sampled)
// verify {"age":{"type":"number"}} x 2,467,326 ops/sec ±3.71% (84 runs sampled)
// verify {"nick":"string"} x 2,094,849 ops/sec ±3.28% (86 runs sampled)
// verify {"nick":{"type":"string"}} x 2,106,839 ops/sec ±2.04% (89 runs sampled)
// verify {"not_exists":"string","required":false} x 846,973 ops/sec ±7.22% (77 runs sampled)
// verify {"sid1":{}} x 1,404,479 ops/sec ±1.32% (89 runs sampled)
// verify {"sid2":{"type":"string","format":{}}} x 1,981,292 ops/sec ±1.62% (91 runs sampled)
// verify {"unit":["y","m","d","w"]} x 2,425,140 ops/sec ±1.30% (89 runs sampled)
// verify {"unit":{"type":"enum","values":["y","m","d","w"]}} x 3,505,832 ops/sec ±3.03% (85 runs sampled)
// verify {"unit":["yy","mm","dd","ww"]} x 1,111,593 ops/sec ±2.30% (84 runs sampled)
// verify {"email":"email"} x 1,117,493 ops/sec ±11.38% (61 runs sampled)
// verify {"password":{"type":"password","compare":"re-password"}} x 966,424 ops/sec ±11.80% (53 runs sampled)
19 changes: 18 additions & 1 deletion index.js
Expand Up @@ -30,6 +30,8 @@ var ID_RE = /^\d+$/;
// http://www.regular-expressions.info/email.html
var EMAIL_RE = /^[a-z0-9\!\#\$\%\&\'\*\+\/\=\?\^\_\`\{\|\}\~\-]+(?:\.[a-z0-9\!\#\$\%\&\'\*\+\/\=\?\^\_\`\{\|\}\~\-]+)*@(?:[a-z0-9](?:[a-z0-9\-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9\-]*[a-z0-9])?$/;

var PASSWORD_RE = /^[\w\`\~\!\@\#\$\%\^\&\*\(\)\-\_\=\+\[\]\{\}\|\;\:\'\"\,\<\.\>\/\?]+$/;

/**
* Simple type map
* @type {Object}
Expand All @@ -50,6 +52,7 @@ var TYPE_MAP = validate.TYPE_MAP = {
object: checkObject,
enum: checkEnum,
email: checkEmail,
password: checkPassword,
};

/**
Expand Down Expand Up @@ -95,7 +98,7 @@ function validate(rules, obj) {
', but the following type was passed: ' + rule.type);
}

var msg = checker(rule, obj[key]);
var msg = checker(rule, obj[key], obj);
if (typeof msg === 'string') {
errors.push({
message: key + ' ' + msg,
Expand Down Expand Up @@ -351,6 +354,20 @@ function checkEmail(rule, value) {
}, value);
}

function checkPassword(rule, value, obj) {
if (!rule.min) {
rule.min = 6;
}
rule.format = PASSWORD_RE;
var error = checkString(rule, value);
if (error) {
return error;
}
if (rule.compare && obj[rule.compare] !== value) {
return 'should equal to ' + rule.compare;
}
}

/**
* check object
* {
Expand Down
62 changes: 59 additions & 3 deletions test/index.test.js
Expand Up @@ -44,7 +44,7 @@ describe('parameter', function () {
var value = {int: 1.1};
var rule = {int: {type: 'int1', required: false}};
validate(rule, value);
}).should.throw('rule type must be one of number, int, integer, string, id, date, dateTime, datetime, boolean, bool, array, object, enum, email, but the following type was passed: int1');
}).should.throw('rule type must be one of number, int, integer, string, id, date, dateTime, datetime, boolean, bool, array, object, enum, email, password, but the following type was passed: int1');
});

it('should throw without rule', function () {
Expand All @@ -56,7 +56,7 @@ describe('parameter', function () {
it('should throw when rule is null', function () {
(function () {
validate({d: null}, {d: 1});
}).should.throw('rule type must be one of number, int, integer, string, id, date, dateTime, datetime, boolean, bool, array, object, enum, email, but the following type was passed: undefined');
}).should.throw('rule type must be one of number, int, integer, string, id, date, dateTime, datetime, boolean, bool, array, object, enum, email, password, but the following type was passed: undefined');
});
});

Expand Down Expand Up @@ -275,6 +275,62 @@ describe('parameter', function () {
});
});

describe('password', function () {
it('should check ok', function () {
should.not.exist(validate({
password: {
type: 'password',
compare: 're-password'
}
}, {
password: '123123~!@',
're-password': '123123~!@',
}));

should.not.exist(validate({
password: {
type: 'password',
}
}, {
password: '123123',
}));
});

it('should check fail', function () {
validate({
password: {
type: 'password',
compare: 're-password'
}
}, {
password: '123123',
're-password': '1231231',
}).should.eql([
{
code: 'invalid',
field: 'password',
message: 'password should equal to re-password'
}
]);

validate({
password: {
type: 'password',
compare: 're-password'
}
}, {
password: '12312',
're-password': '12312',
}).should.eql([
{
code: 'invalid',
field: 'password',
message: 'password length should bigger than 6'
}
]);
});
});

describe('object', function () {
it('should check ok', function () {
var value = {
Expand Down Expand Up @@ -357,7 +413,7 @@ describe('parameter', function () {
var rule = {array: {type: 'array', itemType: 'invalid'}};
(function () {
validate(rule, {array: []});
}).should.throw('rule type must be one of number, int, integer, string, id, date, dateTime, datetime, boolean, bool, array, object, enum, email, but the following type was passed: invalid');
}).should.throw('rule type must be one of number, int, integer, string, id, date, dateTime, datetime, boolean, bool, array, object, enum, email, password, but the following type was passed: invalid');
});

it('should check itemType=object error', function () {
Expand Down

0 comments on commit ee5b4f3

Please sign in to comment.