Skip to content

Commit

Permalink
Merge pull request #9 from Fabricevladimir/feature-include-rule
Browse files Browse the repository at this point in the history
Added includeRules configuration option
  • Loading branch information
Fabricevladimir authored Apr 20, 2020
2 parents d5a3a9c + ddbe0cb commit 2569064
Show file tree
Hide file tree
Showing 12 changed files with 53 additions and 19 deletions.
Empty file removed src/App.css
Empty file.
2 changes: 1 addition & 1 deletion src/validation/lib/digit.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export default function digit(errorMessage) {
* @param {string} value - The value to be validated.
* @return {(boolean | string)} True or an error message if validation failed.
*/
function (value) {
function digit(value) {
return pattern.test(value) || errorMessage;
}
);
Expand Down
2 changes: 1 addition & 1 deletion src/validation/lib/email.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export default function email(errorMessage) {
* @param {string} email - The value to be validated.
* @return {(boolean | string)} True or an error message if validation failed.
*/
function (email) {
function email(email) {
return pattern.test(email) || errorMessage;
}
);
Expand Down
2 changes: 1 addition & 1 deletion src/validation/lib/lowercase.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export default function lowercase(errorMessage) {
* @param {string} value - The value to be validated.
* @return {(boolean | string)} True or an error message if validation failed.
*/
function (value) {
function lowercase(value) {
return pattern.test(value) || errorMessage;
}
);
Expand Down
2 changes: 1 addition & 1 deletion src/validation/lib/matches.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export default function matches(errorMessage) {
* @param {string} value - The value to be validated.
* @return {(boolean | string)} True or an error message if validation failed.
*/
function (value) {
function matches(value) {
return (
new RegExp(`^${escape(matchingValue)}$`).test(value) || errorMessage
);
Expand Down
2 changes: 1 addition & 1 deletion src/validation/lib/maxLength.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export default function maxLength(length, errorMessage) {
* @param {string} value - The value to be validated.
* @return {(boolean | string)} True or an error message if validation failed.
*/
function (value) {
function max(value) {
return new RegExp(`^.{0,${length}}$`).test(value) || errorMessage;
}
);
Expand Down
2 changes: 1 addition & 1 deletion src/validation/lib/minLength.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export default function minLength(length, errorMessage) {
* @param {string} value - The value to be validated.
* @return {(boolean | string)} True or an error message if validation failed.
*/
function (value) {
function min(value) {
return new RegExp(`^.{${length},}$`).test(value) || errorMessage;
}
);
Expand Down
2 changes: 1 addition & 1 deletion src/validation/lib/pattern.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export default function pattern(regexPattern, errorMessage) {
* @param {string} value - The value to be validated.
* @return {(boolean | string)} True or an error message if validation failed.
*/
function (value) {
function pattern(value) {
const validationPattern =
regexPattern.constructor.name === TYPES.REGEX
? regexPattern
Expand Down
2 changes: 1 addition & 1 deletion src/validation/lib/symbol.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export default function symbol(errorMessage) {
* @param {string} value - The value to be validated.
* @return {(boolean | string)} True or an error message if validation failed.
*/
function (value) {
function symbol(value) {
return pattern.test(value) || errorMessage;
}
);
Expand Down
2 changes: 1 addition & 1 deletion src/validation/lib/uppercase.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export default function lowercase(errorMessage) {
* @param {string} value - The value to be validated.
* @return {(boolean | string)} True or an error message if validation failed.
*/
function (value) {
function uppercase(value) {
return pattern.test(value) || errorMessage;
}
);
Expand Down
7 changes: 7 additions & 0 deletions src/validation/schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,13 @@ export default class Schema {

return schema;
}

/**
*
* @param {*} value
* @param {*} options
*/
validate(value, options) {}
}

/************************************
Expand Down
47 changes: 37 additions & 10 deletions src/validation/validate.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import { NO_ERRORS, ERROR_MESSAGES as Errors } from "./constants";
* The validation configurations.
* @typedef {Object} ValidationOptions
* @property {boolean} [includeLabel=false] - Configuration for pre-appending label to the error messages.
* @property {boolean} [includeRules=false] - Configuration for returning errors as an object with each key
* the name of the validator and value the associating error message.
* @property {boolean} [abortEarly=false] - Configuration indicating whether
* to stop validation at the first invalid rule.
*/
Expand All @@ -26,12 +28,17 @@ import { NO_ERRORS, ERROR_MESSAGES as Errors } from "./constants";
* @typedef {Object} PropertyValidationResponse
* @property {boolean} isValid - Property detailing whether the value was validated successfully.
* @property {string[]} errors - The errors present in the property.
* @property {Object} [failedRules] - The names of all the failed validation rules.
*/

/************************************
* Symbolic Constants
************************************/
const DEFAULT_OPTIONS = { includeLabel: false, abortEarly: false };
const DEFAULT_OPTIONS = {
abortEarly: false,
includeRules: false,
includeLabel: false,
};

/**
* Validate a form or string value based on corresponding schema.
Expand Down Expand Up @@ -69,9 +76,10 @@ function validateForm(form, formSchema, options) {
let formIsValid = true;

const formErrors = {};
const formFailedRules = {};

// Check that schema matches form and validate
let schema, errors, isValid;
let schema, errors, isValid, failedRules;
Object.keys(form).forEach((property) => {
// Throw error if property does not have corresponding schema
schema = formSchema[property];
Expand All @@ -85,16 +93,27 @@ function validateForm(form, formSchema, options) {
if (schema.matchingProperty) {
schema = getMatchingSchema(schema, form);
}

// Validate properties and set errors
({ isValid, errors } = validateProperty(form[property], schema, options));
({ isValid, errors, failedRules } = validateProperty(
form[property],
schema,
options
));

if (!isValid) {
formIsValid = false;
formErrors[property] = [...errors];
formFailedRules[property] = { ...failedRules };
}
});

return { isValid: formIsValid, errors: { ...formErrors } };
return !options.includeRules
? { isValid: formIsValid, errors: { ...formErrors } }
: {
isValid: formIsValid,
errors: { ...formErrors },
failedRules: { ...formFailedRules },
};
}

/**
Expand All @@ -115,7 +134,6 @@ function getMatchingSchema(schema, form) {
}

schema.rules[0] = schema.rules[0](matchingValue);

return { ...schema };
}

Expand All @@ -128,19 +146,26 @@ function getMatchingSchema(schema, form) {
*/
function validateProperty(value, schema, options) {
const errors = [];
const failedRules = {};
const { includeRules } = options;

// Empty non-required properties are fine.
if (!schema.required && isEmptyString(value)) {
return { isValid: true, errors };
return !includeRules
? { isValid: true, errors }
: { isValid: true, errors, failedRules };
}

// Required property and empty value
if (schema.required && isEmptyString(value)) {
errors.push(schema.required);
failedRules.required = true;
}

testRules(value, schema, errors, options);
return { isValid: errors.length === NO_ERRORS, errors };
testRules(value, schema, errors, failedRules, options);
return !includeRules
? { isValid: errors.length === NO_ERRORS, errors }
: { isValid: errors.length === NO_ERRORS, errors, failedRules };
}

/**
Expand All @@ -167,10 +192,11 @@ function validateSchema(schema) {
* @param {string} value - The value to be validated.
* @param {object} schema - The schema with the rules to be validated against.
* @param {string[]} errors - The error messages for failed rules.
* @param {object} failedRules - The names of all the failed rules.
* @param {ValidationOptions} options - The validation configurations.
* @returns {void} Nothing.
*/
function testRules(value, schema, errors, options) {
function testRules(value, schema, errors, failedRules, options) {
const { rules, label } = schema;
const { abortEarly, includeLabel } = options;

Expand All @@ -181,6 +207,7 @@ function testRules(value, schema, errors, options) {

if (result !== true) {
errors.push(getErrorMessage(label, result, includeLabel));
failedRules[rules[index].name] = true;

if (abortEarly) break;
}
Expand Down

0 comments on commit 2569064

Please sign in to comment.