Skip to content

Commit

Permalink
Merge d47fd36 into def5a89
Browse files Browse the repository at this point in the history
  • Loading branch information
mushan0x0 committed Oct 30, 2018
2 parents def5a89 + d47fd36 commit 929b80a
Show file tree
Hide file tree
Showing 13 changed files with 216 additions and 52 deletions.
4 changes: 4 additions & 0 deletions .babelrc
@@ -0,0 +1,4 @@
{
"presets": ["env"],
"plugins": ["transform-runtime"]
}
21 changes: 21 additions & 0 deletions README.md
Expand Up @@ -47,6 +47,23 @@ validator.validate({name: "muji"}, (errors, fields) => {
}
// validation passed
});

// PROMISE USAGE
validator.validate({name: "muji"}, (errors, fields) => {
if(errors) {
// validation failed, errors is an array of all errors
// fields is an object keyed by field name with an array of
// errors per field
return handleErrors(errors, fields);
}
// validation passed
})
.then(() => {
// validation passed
})
.catch(({ errors, fields }) => {
return handleErrors(errors, fields);
})
```

### Validate
Expand All @@ -59,6 +76,10 @@ function(source, [options], callback)
* `options`: An object describing processing options for the validation (optional).
* `callback`: A callback function to invoke when validation completes (required).

The method will return a Promise object like:
* `then()`,validation passed
* `catch({ errors, fields })`,validation failed, errors is an array of all errors, fields is an object keyed by field name with an array of
### Options
* `first`: Boolean, Invoke `callback` when the first validation rule generates an error,
Expand Down
57 changes: 40 additions & 17 deletions __tests__/promise.spec.js
@@ -1,19 +1,19 @@
import Schema from '../src/';

describe('validator', () => {
describe('asyncValidator', () => {
it('works', (done) => {
new Schema({
v: [{
validator(rule, value) {
asyncValidator(rule, value) {
return Promise.reject(new Error('e1'));
},
}, {
validator(rule, value) {
asyncValidator(rule, value) {
return Promise.reject(new Error('e2'));
},
}],
v2: [{
validator(rule, value) {
asyncValidator(rule, value) {
return Promise.reject(new Error('e3'));
},
}],
Expand All @@ -31,16 +31,16 @@ describe('validator', () => {
it('first works', (done) => {
new Schema({
v: [{
validator(rule, value) {
asyncValidator(rule, value) {
return Promise.reject(new Error('e1'));
},
}, {
validator(rule, value) {
asyncValidator(rule, value) {
return Promise.reject(new Error('e2'));
},
}],
v2: [{
validator(rule, value) {
asyncValidator(rule, value) {
return Promise.reject(new Error('e3'));
},
}],
Expand All @@ -60,26 +60,26 @@ describe('validator', () => {
it('works for true', (done) => {
new Schema({
v: [{
validator(rule, value) {
asyncValidator(rule, value) {
return Promise.reject(new Error('e1'));
},
}, {
validator(rule, value) {
asyncValidator(rule, value) {
return Promise.reject(new Error('e2'));
},
}],

v2: [{
validator(rule, value) {
asyncValidator(rule, value) {
return Promise.reject(new Error('e3'));
},
}],
v3: [{
validator(rule, value) {
asyncValidator(rule, value) {
return Promise.reject(new Error('e4'));
},
}, {
validator(rule, value) {
asyncValidator(rule, value) {
return Promise.reject(new Error('e5'));
},
}],
Expand All @@ -101,26 +101,26 @@ describe('validator', () => {
it('works for array', (done) => {
new Schema({
v: [{
validator(rule, value) {
asyncValidator(rule, value) {
return Promise.reject(new Error('e1'));
},
}, {
validator(rule, value) {
asyncValidator(rule, value) {
return Promise.reject(new Error('e2'));
},
}],

v2: [{
validator(rule, value) {
asyncValidator(rule, value) {
return Promise.reject(new Error('e3'));
},
}],
v3: [{
validator(rule, value) {
asyncValidator(rule, value) {
return Promise.reject(new Error('e4'));
},
}, {
validator(rule, value) {
asyncValidator(rule, value) {
return Promise.reject(new Error('e5'));
},
}],
Expand All @@ -139,5 +139,28 @@ describe('validator', () => {
done();
});
});
it('Whether to remove the \'Uncaught (in promise)\' warning', async (done) => {
let allCorrect = true;
try {
await new Schema({
async: {
asyncValidator(rule, value) {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject([new Error(rule.message)]);
}, 100);
})
},
message: 'async fails',
},
}).validate({
v: 1,
});
} catch ({ errors }) {
allCorrect = errors.length === 1;
}
expect(allCorrect).toBe(true);
done()
});
});
});
Empty file added examples/async-validator.html
Empty file.
30 changes: 30 additions & 0 deletions examples/async-validator.js
@@ -0,0 +1,30 @@
/* eslint no-console:0 */

import Schema from 'async-validator';

const schema = new Schema({
validator0: {
asyncValidator(rule, value, callback) {
setTimeout(() => callback('Validator0 message'), 100);
},
},
validator1: {
asyncValidator() {
return new Promise((resolve, reject) => {
setTimeout(() => reject('Validator1 message'), 100);
});
},
},
});

schema.validate({
validator0: '0',
validator1: '1',
}, (errors, fields) => {
console.log('errors');
console.log(errors);
console.log('fields');
console.log(fields);
});

console.log('end');
19 changes: 12 additions & 7 deletions examples/simple.js
@@ -1,4 +1,4 @@
/* eslint no-console:0 */
/* eslint no-console:0 no-unused-vars:0 */

import Schema from 'async-validator';

Expand All @@ -24,7 +24,7 @@ const schema = new Schema({
min: 5,
},
async: {
validator(rule, value, callback) {
asyncValidator(rule, value, callback) {
setTimeout(() => {
callback(rule.message);
}, 100);
Expand All @@ -34,10 +34,12 @@ const schema = new Schema({
},
},
async: {
validator(rule, value, callback) {
setTimeout(() => {
callback([new Error(rule.message)]);
}, 100);
asyncValidator(rule, value) {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject([new Error(rule.message)]);
}, 100);
});
},
message: 'async fails',
},
Expand All @@ -54,6 +56,9 @@ schema.validate({
console.log(errors);
console.log('fields');
console.log(fields);
});
})
.catch(({ errors, fields }) => {
console.log(errors, fields);
});

console.log('end');
Empty file added examples/validator.html
Empty file.
51 changes: 51 additions & 0 deletions examples/validator.js
@@ -0,0 +1,51 @@
/* eslint no-console:0 no-unused-vars:0 */

import Schema from 'async-validator';

const schema = new Schema({
validator0: {
validator(rule, value) {
return true;
},
},
validator1: {
validator(rule, value) {
return false;
},
},
validator2: {
validator(rule, value) {
return false;
},
message: 'Customize error messages',
},
validator3: {
validator(rule, value) {
return [
'Error message 1',
'Error message 2',
'Error message 3',
];
},
},
validator4: {
validator(rule, value, callback) {
setTimeout(() => callback('Compatible with older USES'), 100);
},
},
});

schema.validate({
validator0: '0',
validator1: '1',
validator2: '2',
validator3: '3',
validator4: '4',
}, (errors, fields) => {
console.log('errors');
console.log(errors);
console.log('fields');
console.log(fields);
});

console.log('end');
4 changes: 3 additions & 1 deletion package.json
Expand Up @@ -44,8 +44,10 @@
"coverage": "jest --coverage && cat ./coverage/lcov.info | coveralls"
},
"devDependencies": {
"babel-plugin-transform-runtime": "^6.23.0",
"babel-preset-env": "^1.7.0",
"coveralls": "^2.13.1",
"jest": "20.x",
"jest": "21.x",
"pre-commit": "1.x",
"rc-tools": "6.x"
},
Expand Down
32 changes: 19 additions & 13 deletions src/index.js
@@ -1,4 +1,4 @@
import { format, complementError, asyncMap, warning, deepMerge } from './util';
import { format, complementError, asyncMap, warning, deepMerge, convertFieldsError } from './util';
import validators from './validator/';
import { messages as defaultMessages, newMessages } from './messages';

Expand Down Expand Up @@ -39,7 +39,7 @@ Schema.prototype = {
}
}
},
validate(source_, o = {}, oc) {
validate(source_, o = {}, oc = () => {}) {
let source = source_;
let options = o;
let callback = oc;
Expand All @@ -51,17 +51,16 @@ Schema.prototype = {
if (callback) {
callback();
}
return;
return Promise.resolve();
}
function complete(results) {
let i;
let field;
let errors = [];
let fields = {};

function add(e) {
if (Array.isArray(e)) {
errors = errors.concat.apply(errors, e);
errors = errors.concat(...e);
} else {
errors.push(e);
}
Expand All @@ -74,11 +73,7 @@ Schema.prototype = {
errors = null;
fields = null;
} else {
for (i = 0; i < errors.length; i++) {
field = errors[i].field;
fields[field] = fields[field] || [];
fields[field].push(errors[i]);
}
fields = convertFieldsError(errors);
}
callback(errors, fields);
}
Expand Down Expand Up @@ -132,7 +127,7 @@ Schema.prototype = {
});
});
const errorFields = {};
asyncMap(series, options, (data, doIt) => {
return asyncMap(series, options, (data, doIt) => {
const rule = data.rule;
let deep = (rule.type === 'object' || rule.type === 'array') &&
(typeof (rule.fields) === 'object' || typeof (rule.defaultField) === 'object');
Expand Down Expand Up @@ -211,8 +206,19 @@ Schema.prototype = {
}
}

const res = rule.validator(
rule, data.value, cb, data.source, options);
let res;
if (rule.asyncValidator) {
res = rule.asyncValidator(rule, data.value, cb, data.source, options);
} else if (rule.validator) {
res = rule.validator(rule, data.value, cb, data.source, options);
if (res === true) {
cb();
} else if (res === false) {
cb(rule.message || `${rule.field} fails`);
} else if (res instanceof Array) {
cb(res);
}
}
if (res && res.then) {
res.then(() => cb(), e => cb(e));
}
Expand Down
1 change: 1 addition & 0 deletions src/rule/enum.js
@@ -1,4 +1,5 @@
import * as util from '../util';

const ENUM = 'enum';

/**
Expand Down

0 comments on commit 929b80a

Please sign in to comment.