Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ lib/ReadmeResources/
lib/coverage/
yarn.lock
.vscode/
npm-debug.log
npm-debug.log
lib/package-lock\.json
5 changes: 3 additions & 2 deletions lib/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "lc-form-validation",
"version": "1.0.0",
"version": "1.0.3",
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1.0.3 version was the last published

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We must upgrade to 1.1.0 after finish all branches?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree, let's go for 1.1.0 once we have as well de formtofield thing

"description": "lcFormValidation is an async form validation library heavily based on JavaScript (no HTML attributes or annotations). lcFormValidation is third party / framework agnostic so it can be easily integrated with frameworks like React.",
"main": "dist/lc-form-validation.js",
"scripts": {
Expand Down Expand Up @@ -83,6 +83,7 @@
}
],
"dependencies": {
"es6-promise": "4.1.0"
"es6-promise": "4.1.0",
"lodash.get": "^4.4.2"
}
}
76 changes: 76 additions & 0 deletions lib/src/spec/validationEngineValidateForm.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,82 @@ describe('ValidationEngine Validate Form', () => {
done();
});
});

it('Spec #9 => should pass validation when feeding viewModel with nested properties, fullname.firstName equals "john" and is validation required', (done) => {
// Arrange
const validationEngine: ValidationEngine = new ValidationEngine();
const viewModel = {
fullname: {
firstName: 'john',
},
};

// Act
validationEngine.addFieldValidation('fullname.firstName',
(value, vm): Promise<FieldValidationResult> => {
let isFieldInformed: boolean = (value != null && value.length > 0);
let errorInfo: string = (isFieldInformed) ? "" : "Mandatory field";

const validationResult: FieldValidationResult = new FieldValidationResult();
validationResult.type = "REQUIRED";
validationResult.succeeded = isFieldInformed;
validationResult.errorMessage = errorInfo;

return Promise.resolve(validationResult);
}
);

validationEngine.validateForm(viewModel)
.then((formValidationResult: FormValidationResult) => {
expect(formValidationResult.succeeded).to.be.true;

expect(formValidationResult.fieldErrors).to.have.length(1);

expect(formValidationResult.fieldErrors[0].succeeded).to.be.true;
expect(formValidationResult.fieldErrors[0].key).to.be.equal('fullname.firstName');
expect(formValidationResult.fieldErrors[0].type).to.equal('REQUIRED');
expect(formValidationResult.fieldErrors[0].errorMessage).to.equal('');
done();
});
});

it('Spec #10 => should fail validation when feeding viewModel with nested properties, fullname.firstName equals "" and is validation required', (done) => {
// Arrange
const validationEngine: ValidationEngine = new ValidationEngine();
const viewModel = {
fullname: {
firstName: '',
},
};

// Act
validationEngine.addFieldValidation('fullname.firstName',
(value, vm): Promise<FieldValidationResult> => {
let isFieldInformed: boolean = (value != null && value.length > 0);
let errorInfo: string = (isFieldInformed) ? "" : "Mandatory field";

const validationResult: FieldValidationResult = new FieldValidationResult();
validationResult.type = "REQUIRED";
validationResult.succeeded = isFieldInformed;
validationResult.errorMessage = errorInfo;

return Promise.resolve(validationResult);
}
);

validationEngine.validateForm(viewModel)
.then((formValidationResult: FormValidationResult) => {
expect(formValidationResult.succeeded).to.be.false;

expect(formValidationResult.fieldErrors).to.have.length(1);

expect(formValidationResult.fieldErrors[0].succeeded).to.be.false;
expect(formValidationResult.fieldErrors[0].key).to.be.equal('fullname.firstName');
expect(formValidationResult.fieldErrors[0].type).to.equal('REQUIRED');
expect(formValidationResult.fieldErrors[0].errorMessage).to.equal('Mandatory field');
done();
});
});
});

describe('Group #2 => When calling validateForm and addFormValidation with async function', () => {
Expand Down
85 changes: 85 additions & 0 deletions lib/src/spec/validationEngineValidateSingleField.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,4 +133,89 @@ describe('lcFormValidation simple form', () => {
expect(promise).to.eventually.be.rejected.and.notify(done);
});

it('should pass validation when feeding viewModel with nested properties, value equals "john" and validation required',
(done) => {
// Arrange
const formValidationBase: ValidationEngine = new ValidationEngine();
const viewModel = {
id: '1',
fullname: {
firstName: '',
secondName: 'doe',
},
};

const value = 'john';

// Act
formValidationBase.addFieldValidation('fullname.firstName',
(value, vm): Promise<FieldValidationResult> => {
let isFieldInformed: boolean = (value != null && value.length > 0);

let errorInfo: string = (isFieldInformed) ? "" : "Mandatory field";

const validationResult: FieldValidationResult = new FieldValidationResult();
validationResult.type = "REQUIRED";
validationResult.succeeded = isFieldInformed;
validationResult.errorMessage = errorInfo;

return Promise.resolve(validationResult);
}
);

formValidationBase
.validateField(viewModel, 'fullname.firstName', value)
.then((fieldValidationResult: FieldValidationResult) => {

// Assert
expect(fieldValidationResult.key).to.be.equal('fullname.firstName');
expect(fieldValidationResult.type).to.equal('REQUIRED');
expect(fieldValidationResult.succeeded).to.be.true;
expect(fieldValidationResult.errorMessage).to.be.empty;
done();
});
});

it('should fail validation when feeding viewModel with nested properties, value equals "" and validation required',
(done) => {
// Arrange
const formValidationBase: ValidationEngine = new ValidationEngine();
const viewModel = {
id: '1',
fullname: {
firstName: '',
secondName: 'doe',
},
};

const value = '';

// Act
formValidationBase.addFieldValidation('fullname.firstName',
(value, vm): Promise<FieldValidationResult> => {
let isFieldInformed: boolean = (value != null && value.length > 0);

let errorInfo: string = (isFieldInformed) ? "" : "Mandatory field";

const validationResult: FieldValidationResult = new FieldValidationResult();
validationResult.type = "REQUIRED";
validationResult.succeeded = isFieldInformed;
validationResult.errorMessage = errorInfo;

return Promise.resolve(validationResult);
}
);

formValidationBase
.validateField(viewModel, 'fullname.firstName', value)
.then((fieldValidationResult: FieldValidationResult) => {

// Assert
expect(fieldValidationResult.key).to.be.equal('fullname.firstName');
expect(fieldValidationResult.type).to.equal('REQUIRED');
expect(fieldValidationResult.succeeded).to.be.false;
expect(fieldValidationResult.errorMessage).to.equal('Mandatory field');
done();
});
});
});
39 changes: 29 additions & 10 deletions lib/src/spec/validationsDispatcher.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ describe('ValidationsDispatcher', () => {
});
});

it('Spec #11 => should return empty FieldValidationResult and calls to validation functions ' +
it('Spec #12 => should return empty FieldValidationResult and calls to validation functions ' +
'When passing vm equals undefined, value equals undefined and validationsPerField equals array with one item ' +
'equals validation function resolving a fieldValidationResult equals ""', (done) => {
//Arrange
Expand Down Expand Up @@ -433,7 +433,7 @@ describe('ValidationsDispatcher', () => {
});
});

it('Spec #12 => should return undefined FieldValidationResult and calls to first validation function ' +
it('Spec #13 => should return undefined FieldValidationResult and calls to first validation function ' +
'When passing vm equals undefined, value equals undefined and validationsPerField equals array with two items ' +
'first equals validation function resolving a fieldValidationResult equals undefined' +
'second equals successful validation function', (done) => {
Expand Down Expand Up @@ -484,7 +484,7 @@ describe('ValidationsDispatcher', () => {
});
});

it('Spec #13 => should return undefined FieldValidationResult and calls to first validation function ' +
it('Spec #14 => should return undefined FieldValidationResult and calls to first validation function ' +
'When passing vm equals undefined, value equals undefined and validationsPerField equals array with two items ' +
'first equals validation function resolving a fieldValidationResult equals undefined' +
'second equals failed validation function', (done) => {
Expand Down Expand Up @@ -534,7 +534,7 @@ describe('ValidationsDispatcher', () => {
});
});

it('Spec #14 => should return failed and key equals "test1" FieldValidationResult and calls to first validation function ' +
it('Spec #15 => should return failed and key equals "test1" FieldValidationResult and calls to first validation function ' +
'When passing vm equals undefined, value equals undefined and validationsPerField equals array with two items ' +
'first equals failed validation function' +
'second equals validation function resolving a fieldValidationResult equals undefined', (done) => {
Expand Down Expand Up @@ -586,7 +586,7 @@ describe('ValidationsDispatcher', () => {
});
});

it('Spec #15 => should return undefined FieldValidationResult and calls to first and second validation functions ' +
it('Spec #16 => should return undefined FieldValidationResult and calls to first and second validation functions ' +
'When passing vm equals undefined, value equals undefined and validationsPerField equals array with two items ' +
'first equals successful validation function' +
'second equals validation function resolving a fieldValidationResult equals undefined', (done) => {
Expand Down Expand Up @@ -636,7 +636,7 @@ describe('ValidationsDispatcher', () => {
});
});

it('should pass customParams to its proper validationFunction', (done) => {
it('Spec #17 => should pass customParams to its proper validationFunction', (done) => {
//Arrange
const vm = undefined;
const value = undefined;
Expand Down Expand Up @@ -800,7 +800,7 @@ describe('ValidationsDispatcher', () => {
});

it('Spec #9 => should return empty array and should not call to validationFn ' +
'when passing vm equals { }, vmKeys as non empty array and validationFn equals function', () => {
'when passing vm equals { testVmProperty: "" }, vmKeys equals ["otherProperty"] and validationFn equals function', () => {
//Arrange
const vm = {
testVmProperty: ''
Expand All @@ -816,8 +816,8 @@ describe('ValidationsDispatcher', () => {
expect(validationFnSpy.called).to.be.false;
});

it('Spec #10 => should not return empty array with one item and it calls to validationFn ' +
'when passing vm equals { testVmProperty: "test" }, vmKeys equals [] and validationFn equals function', () => {
it('Spec #10 => should return array with one item and it calls to validationFn ' +
'when passing vm equals { testVmProperty: "test" }, vmKeys equals [testVmProperty] and validationFn equals function', () => {
//Arrange
const vm = {
testVmProperty: 'test'
Expand All @@ -828,6 +828,25 @@ describe('ValidationsDispatcher', () => {
//Act
const fieldValidationResultPromises = validationsDispatcher.fireAllFieldsValidations(vm, vmKeys, validationFnSpy);

//Ass
expect(fieldValidationResultPromises).to.have.length(1);
expect(validationFnSpy.called).to.be.true;
});

it('Spec #11 => should return array with one item and it calls to validationFn ' +
'when passing vm equals { test: { property: "test"} }, vmKeys equals ["test.property"] and validationFn equals function', () => {
//Arrange
const vm = {
test: {
property: 'test',
},
};
const vmKeys = ['test.property'];
const validationFnSpy = sinon.spy();

//Act
const fieldValidationResultPromises = validationsDispatcher.fireAllFieldsValidations(vm, vmKeys, validationFnSpy);

//Ass
expect(fieldValidationResultPromises).to.have.length(1);
expect(validationFnSpy.called).to.be.true;
Expand Down Expand Up @@ -957,7 +976,7 @@ describe('ValidationsDispatcher', () => {
it('Spec #9 => should return array with one item and it calls to validationFn' +
'When passing vm equals function, validations equals array with one validationFn', () => {
//Arrange
const vm = function () {
const vm = function() {
return "this is a function";
};
const validationFnSpy = sinon.spy();
Expand Down
5 changes: 2 additions & 3 deletions lib/src/validationsDispatcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@ import {
FieldValidationResult,
ValidationResult,
FormValidationFunction,
FieldValidationFunction,
FieldValidation,
} from './entities';
import { consts } from './consts';
import get from 'lodash.get';

class ValidationParams {
constructor(
Expand Down Expand Up @@ -75,7 +74,7 @@ export class ValidationDispatcher {

if (this.areParametersDefined(vm, validationFn)) {
fieldsToValidate.forEach((field) => {
const vmFieldValue = vm[field];
const vmFieldValue = get(vm, field, undefined);
if (vmFieldValue !== undefined) {
const fieldValidationResultsPromise = validationFn(vm, field, vmFieldValue);
fieldValidationResultsPromises.push(fieldValidationResultsPromise);
Expand Down
3 changes: 1 addition & 2 deletions lib/webpack.config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
var path = require("path");
var webpack = require("webpack");
var libraryName = 'lc-form-validation';
var CopyWebpackPlugin = require('copy-webpack-plugin');

Expand Down Expand Up @@ -39,7 +38,7 @@ var config = {
]
},

plugins: [
plugins: [
new CopyWebpackPlugin([
{ from: '../../README.md', to: 'README.md' },
{ from: '../../ReadmeResources', to: 'ReadmeResources' }
Expand Down