Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: custom error message #68

Merged
merged 5 commits into from
Mar 14, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
feat: custom message for any rule type
  • Loading branch information
sarike committed Jun 22, 2019
commit 8bf36a075bbc1cec84d8fc8669ea2ed4bbbb6528
74 changes: 45 additions & 29 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ class Parameter {
}
}

message(rule, defaultMessage) {
return this.t(rule.message || defaultMessage);
message(rule, key, defaultMessage) {
return rule.message && rule.message[key] || defaultMessage;
}

/**
Expand Down Expand Up @@ -93,7 +93,7 @@ class Parameter {
if (!has) {
if (rule.required !== false) {
errors.push({
message: this.t('required'),
message: this.message(rule, 'required', this.t('required')),
field: key,
code: this.t('missing_field')
});
Expand All @@ -115,7 +115,7 @@ class Parameter {
var msg = checker.call(self, rule, obj[key], obj);
if (typeof msg === 'string') {
errors.push({
message: this.message(rule, msg),
message: msg,
code: this.t('invalid'),
field: key
});
Expand Down Expand Up @@ -258,6 +258,13 @@ function formatRule(rule) {
rule.required = false;
}

rule.message = rule.message || {}
if (typeof rule.message === 'string') {
rule.message = {
[rule.type]: rule.message,
}
}

return rule;
}

Expand Down Expand Up @@ -321,15 +328,15 @@ function convert(rule, obj, key, defaultConvert) {

function checkInt(rule, value) {
if (typeof value !== 'number' || value % 1 !== 0) {
return this.t('should be an integer');
return this.message(rule, 'int', this.t('should be an integer'));
}

if (rule.hasOwnProperty('max') && value > rule.max) {
return this.t('should smaller than %s', rule.max);
return this.message(rule, 'max', this.t('should smaller than %s', rule.max));
}

if (rule.hasOwnProperty('min') && value < rule.min) {
return this.t('should bigger than %s', rule.min);
return this.message(rule, 'min', this.t('should bigger than %s', rule.min));
}
}

Expand All @@ -348,13 +355,13 @@ function checkInt(rule, value) {

function checkNumber(rule, value) {
if (typeof value !== 'number' || isNaN(value)) {
return this.t('should be a number');
return this.message(rule, 'number', this.t('should be a number'));
}
if (rule.hasOwnProperty('max') && value > rule.max) {
return this.t('should smaller than %s', rule.max);
return this.message(rule, 'max', this.t('should smaller than %s', rule.max));
}
if (rule.hasOwnProperty('min') && value < rule.min) {
return this.t('should bigger than %s', rule.min);
return this.message(rule, 'min', this.t('should bigger than %s', rule.min));
}
}

Expand All @@ -376,7 +383,7 @@ function checkNumber(rule, value) {

function checkString(rule, value) {
if (typeof value !== 'string') {
return this.t('should be a string');
return this.message(rule, rule.type || 'string', this.t('should be a string'));
}

// if required === false, set allowEmpty to true by default
Expand All @@ -390,18 +397,18 @@ function checkString(rule, value) {

if (!value) {
if (allowEmpty) return;
return this.t('should not be empty');
return this.message(rule, 'allowEmpty', '') || this.message(rule, 'empty', '') || this.t('should not be empty');
}

if (rule.hasOwnProperty('max') && value.length > rule.max) {
return this.t('length should smaller than %s', rule.max);
return this.message(rule, 'max', this.t('length should smaller than %s', rule.max));
}
if (rule.hasOwnProperty('min') && value.length < rule.min) {
return this.t('length should bigger than %s', rule.min);
return this.message(rule, 'min', this.t('length should bigger than %s', rule.min));
}

if (rule.format && !rule.format.test(value)) {
return this.t('should match %s', rule.format);
return this.message(rule, 'format', this.t('should match %s', rule.format));
}
}

Expand All @@ -416,7 +423,10 @@ function checkString(rule, value) {
*/

function checkId(rule, value) {
return checkString.call(this, { format: ID_RE, allowEmpty: rule.allowEmpty }, value);
const errorMessage = checkString.call(this, { format: ID_RE, allowEmpty: rule.allowEmpty }, value);
if (errorMessage) {
return this.message(rule, 'id', errorMessage);
}
}

/**
Expand All @@ -430,7 +440,10 @@ function checkId(rule, value) {
*/

function checkDate(rule, value) {
return checkString.call(this, { format: DATE_TYPE_RE, allowEmpty: rule.allowEmpty }, value);
const errorMessage = checkString.call(this, { format: DATE_TYPE_RE, allowEmpty: rule.allowEmpty }, value);
if (errorMessage) {
return this.message(rule, 'date', errorMessage);
}
}

/**
Expand All @@ -444,7 +457,10 @@ function checkDate(rule, value) {
*/

function checkDateTime(rule, value) {
return checkString.call(this, { format: DATETIME_TYPE_RE, allowEmpty: rule.allowEmpty }, value);
const errorMessage = checkString.call(this, { format: DATETIME_TYPE_RE, allowEmpty: rule.allowEmpty }, value);
if (errorMessage) {
return this.message(rule, 'dateTime', errorMessage);
}
}

/**
Expand All @@ -458,7 +474,7 @@ function checkDateTime(rule, value) {

function checkBoolean(rule, value) {
if (typeof value !== 'boolean') {
return this.t('should be a boolean');
return this.message(rule, 'bool', '') || this.message(rule, 'boolean', '') || this.t('should be a boolean');
}
}

Expand All @@ -479,7 +495,7 @@ function checkEnum(rule, value) {
throw new TypeError('check enum need array type values');
}
if (rule.values.indexOf(value) === -1) {
return this.t('should be one of %s', rule.values.join(', '));
return this.message(rule, 'enum', this.t('should be one of %s', rule.values.join(', ')));
}
}

Expand All @@ -498,7 +514,7 @@ function checkEmail(rule, value) {
allowEmpty: rule.allowEmpty,
}, value);
if (errorMessage) {
return this.t('should be an email');
return this.message(rule, 'email', this.t('should be an email'));
}
}

Expand All @@ -519,10 +535,10 @@ function checkPassword(rule, value, obj) {
rule.format = PASSWORD_RE;
var error = checkString.call(this, rule, value);
if (error) {
return error;
return this.message(rule, 'password', error);
}
if (rule.compare && obj[rule.compare] !== value) {
return this.t('should equal to %s', rule.compare);
return this.message(rule, 'compare', this.t('should equal to %s', rule.compare));
}
}

Expand All @@ -541,7 +557,7 @@ function checkUrl(rule, value) {
allowEmpty: rule.allowEmpty
}, value);
if (error) {
return this.t('should be a url')
return this.message(rule, 'url', this.t('should be a url'));
}
}

Expand All @@ -559,7 +575,7 @@ function checkUrl(rule, value) {

function checkObject(rule, value) {
if (typeof value !== 'object') {
return this.t('should be an object');
return this.message(rule, 'object', this.t('should be an object'));
}

if (rule.rule) {
Expand Down Expand Up @@ -591,14 +607,14 @@ function checkObject(rule, value) {

function checkArray(rule, value) {
if (!Array.isArray(value)) {
return this.t('should be an array');
return this.message(rule, 'array', this.t('should be an array'));
}

if (rule.hasOwnProperty('max') && value.length > rule.max) {
return this.t('length should smaller than %s', rule.max);
return this.message(rule, 'max', this.t('length should smaller than %s', rule.max));
}
if (rule.hasOwnProperty('min') && value.length < rule.min) {
return this.t('length should bigger than %s', rule.min);
return this.message(rule, 'min', this.t('length should bigger than %s', rule.min));
}

if (!rule.itemType) {
Expand All @@ -624,7 +640,7 @@ function checkArray(rule, value) {
if (typeof errs === 'string') {
errors.push({
field: index,
message: self.message(subRule, errs),
message: errs,
code: self.t('invalid')
});
}
Expand Down
77 changes: 76 additions & 1 deletion test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,21 @@ describe('parameter', () => {
it('should check error with custom message', () => {
var value = { int: '1' };
var rule = { int: {type: 'int', message: 'custom message'}};
var rule2 = { int: {type: 'int', message: { int: 'custom message'}}};
parameter.validate(rule, value)[0].message.should.equal('custom message');
parameter.validate(rule2, value)[0].message.should.equal('custom message');
});

it('should check error with custom min message', () => {
var value = { int: 1 };
var rule = { int: {type: 'int', min: 2, message: { min: '不能小于2' }}};
parameter.validate(rule, value)[0].message.should.equal('不能小于2');
});

it('should check error with custom max message', () => {
var value = { int: 10 };
var rule = { int: {type: 'int', max: 5, message: { max: '不能大于5' }}};
parameter.validate(rule, value)[0].message.should.equal('不能大于5');
});
});

Expand Down Expand Up @@ -163,6 +177,26 @@ describe('parameter', () => {
var rule = { number: {type: 'number', max: 100, min: 0 }};
parameter.validate(rule, value)[0].message.should.equal('should bigger than 0');
});

it('should check error with custom message', () => {
var value = { number: '-1' };
var rule = { number: {type: 'number', message: 'custom message'}};
var rule2 = { number: {type: 'number', message: { number: 'custom message'}}};
parameter.validate(rule, value)[0].message.should.equal('custom message');
parameter.validate(rule2, value)[0].message.should.equal('custom message');
});

it('should check error with custom min message', () => {
var value = { number: 1 };
var rule = { number: {type: 'number', min: 2, message: { min: '不能小于2' }}};
parameter.validate(rule, value)[0].message.should.equal('不能小于2');
});

it('should check error with custom max message', () => {
var value = { number: 10 };
var rule = { number: {type: 'number', max: 5, message: { max: '不能大于5' }}};
parameter.validate(rule, value)[0].message.should.equal('不能大于5');
});
});

describe('string', () => {
Expand All @@ -180,6 +214,10 @@ describe('parameter', () => {
parameter.validate(rule, value)[0].message.should.equal('should not be empty');
rule = { string: {type: 'string', empty: false }};
parameter.validate(rule, value)[0].message.should.equal('should not be empty');
rule = { string: {type: 'string', empty: false, message: { empty: '不能为空' } }};
parameter.validate(rule, value)[0].message.should.equal('不能为空');
rule = { string: {type: 'string', empty: false, message: { allowEmpty: '不能为空' } }};
parameter.validate(rule, value)[0].message.should.equal('不能为空');
});

it('should check with rule.trim', () => {
Expand All @@ -191,18 +229,24 @@ describe('parameter', () => {
var value = { string: 'hello' };
var rule = { string: {type: 'string', max: 4, min: 1 }};
parameter.validate(rule, value)[0].message.should.equal('length should smaller than 4');
rule = { string: {type: 'string', max: 4, min: 1, message: { max: '不能多于4个字符'} }};
parameter.validate(rule, value)[0].message.should.equal('不能多于4个字符');
});

it('should check min error', () => {
var value = { string: 'hello' };
var rule = { string: {type: 'string', max: 100, min: 10 }};
parameter.validate(rule, value)[0].message.should.equal('length should bigger than 10');
rule = { string: {type: 'string', max: 100, min: 10, message: { min: '不能少于10个字符'} }};
parameter.validate(rule, value)[0].message.should.equal('不能少于10个字符');
});

it('should check format error', () => {
var value = {string: 'hello'};
var rule = {string: /\d+/};
var rule = {string: { type: 'string', format: /\d+/ }};
parameter.validate(rule, value)[0].message.should.equal('should match /\\d+/');
rule = {string: { type: 'string', format: /\d+/, message: { format: '格式不正确' }}};
parameter.validate(rule, value)[0].message.should.equal('格式不正确');
});

it('should check allowEmpty with format ok', () => {
Expand Down Expand Up @@ -244,6 +288,8 @@ describe('parameter', () => {
var value = {id : '0524x' };
var rule = {id: 'id'};
parameter.validate(rule, value)[0].message.should.equal('should match /^\\d+$/');
rule = {id: { type: 'id', message: 'ID 格式不正确' }};
parameter.validate(rule, value)[0].message.should.equal('ID 格式不正确');
});
});

Expand All @@ -259,6 +305,8 @@ describe('parameter', () => {
var value = {date : '2014-xx-xx' };
var rule = {date: 'date'};
parameter.validate(rule, value)[0].message.should.equal('should match /^\\d{4}\\-\\d{2}\\-\\d{2}$/');
rule = {date: { type: 'date', message: '日期格式不正确'}};
parameter.validate(rule, value)[0].message.should.equal('日期格式不正确');
});

it('should check allowEmpty ok', () => {
Expand All @@ -282,6 +330,8 @@ describe('parameter', () => {
var value = {dateTime : '2014-11-11 00:xx:00' };
var rule = {dateTime: 'dateTime'};
parameter.validate(rule, value)[0].message.should.equal('should match /^\\d{4}\\-\\d{2}\\-\\d{2} \\d{2}:\\d{2}:\\d{2}$/');
rule = {dateTime: { type: 'dateTime', message: "时间格式不正确" }};
parameter.validate(rule, value)[0].message.should.equal('时间格式不正确');
});

it('should datetime alias to dateTime', () => {
Expand Down Expand Up @@ -313,6 +363,10 @@ describe('parameter', () => {
var value = {boolean : '2014-11-11 00:xx:00' };
var rule = {boolean: 'boolean'};
parameter.validate(rule, value)[0].message.should.equal('should be a boolean');
rule = {boolean: { type: 'boolean', message: '应该是一个布尔值' }};
parameter.validate(rule, value)[0].message.should.equal('应该是一个布尔值');
rule = {boolean: { type: 'bool', message: '应该是一个布尔值' }};
parameter.validate(rule, value)[0].message.should.equal('应该是一个布尔值');
});
});

Expand All @@ -335,6 +389,8 @@ describe('parameter', () => {
var value = {enum : 4 };
var rule = {enum: [1, 2, 3]};
parameter.validate(rule, value)[0].message.should.equal('should be one of 1, 2, 3');
rule = {enum: { type: 'enum', values: [1, 2, 3], message: '不合法的枚举值' }};
parameter.validate(rule, value)[0].message.should.equal('不合法的枚举值');
});
});

Expand Down Expand Up @@ -426,6 +482,25 @@ describe('parameter', () => {
}
]);

parameter.validate({
password: {
type: 'password',
compare: 're-password',
message: {
compare: '两次输入的密码不一致'
}
}
}, {
password: '123123',
're-password': '1231231',
}).should.eql([
{
code: 'invalid',
field: 'password',
message: '两次输入的密码不一致'
}
]);

parameter.validate({
password: {
type: 'password',
Expand Down