diff --git a/README.md b/README.md index 269a82d..c0850d2 100755 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ +

Code example @@ -85,6 +86,21 @@ Iodine.isValid(item_1, ['required', 'integer']); // true Iodine.isValid(item_2, ['required', 'integer']); // false ``` +### Schema validation + +If you want to compare an object against a schema. In other words, you want to run a list of checks against a list of values, then you can use the `isValidSchema` helper method. **Note** : This method uses `isValid`under the hood, hence it returns a `boolean`. + +```js +Iodine.isValidSchema( + { email: 'welcome@to.iodine', password: 'abcdefgh', fullname: 'John Doe' }, + { + email: [ 'required' , 'email' ], + password: [ 'required' , 'minLength:6' ], + fullname: [ 'required' , 'minLength:3' ] + } +); // true +``` + ## Additional parameters Some rules require extra parameters e.g. diff --git a/src/iodine.js b/src/iodine.js index 84078a4..542997e 100644 --- a/src/iodine.js +++ b/src/iodine.js @@ -421,6 +421,29 @@ export class Iodine { return this.is(value, rules) === true; } + /** + * Determine whether the given dictionary of values meets the given schema. + * + */ + isValidSchema(values = {}, schema = {}) { + const keys = Object.keys(schema); + + if(keys.length === 0) return true; + + for(let i = 0; i < keys.length; i++) { + const key = keys[i]; + + if(!values.hasOwnProperty(key)) return false; + + const value = values[key]; + const rules = schema[key]; + + if (!this.isValid(value, rules)) return false; + } + + return true; + } + /** * Replace the default error messages with a new set. * diff --git a/tests/test.js b/tests/test.js index 00d53ac..1511175 100644 --- a/tests/test.js +++ b/tests/test.js @@ -397,6 +397,53 @@ test('return true/false', () => { expect(Iodine.isValid(undefined, ['optional', 'integer', 'min:7', 'max:10'])).toBe(true); }); +/** + * Confirm that the 'isValidSchema' method returns the right value against multiple schemas. + * + */ +test('schema validation', () => { + + expect( + Iodine.isValidSchema( + { }, + { + website: [ 'required' , 'url' ], + ping: [ 'required' , 'integer' ], + } + ) + ).toBe(false); + + expect( + Iodine.isValidSchema( + { email: 'welcome@to.iodine', password: 'abcdefgh', fullname: 'John Doe' }, + { + email: [ 'required' , 'email' ], + password: [ 'required' , 'minLength:6' ], + fullname: [ 'required' , 'minLength:3' ] + } + ) + ).toBe(true); + + expect( + Iodine.isValidSchema( + { website: 'https://iodine.is', ping: 'ninety' }, + { + website: [ 'required' , 'url' ], + } + ) + ).toBe(true); + + expect( + Iodine.isValidSchema( + { website: 'https://iodine.io', ping: 'ninety' }, + { + website: [ 'required' , 'url' ], + ping: [ 'required' , 'integer' ], + } + ) + ).toBe(false); +}); + /** * Confirm that the 'is' method can handle rules that contain semicolons. * @@ -541,4 +588,4 @@ test('it can add async custom rules', async () => { expect(await Iodine.asyncIs(1, ['required', 'timeoutEquals:2'])).toBe('timeoutEquals:2'); expect(await Iodine.asyncIsValid(1, ['required', 'integer', 'timeoutEquals:1'])).toBe(true); expect(await Iodine.asyncIsValid(1, ['required', 'integer', 'timeoutEquals:2'])).toBe(false); -}); \ No newline at end of file +});