Skip to content

Commit

Permalink
Merge branch 'feature/84-Improve-get-formValidationResult.fieldErrors'
Browse files Browse the repository at this point in the history
  • Loading branch information
nasdan committed Sep 4, 2018
2 parents a8ed619 + bd68022 commit 1f44dff
Show file tree
Hide file tree
Showing 21 changed files with 305 additions and 203 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ lib/coverage/
yarn.lock
.vscode/
npm-debug.log
lib/package-lock\.json
package-lock\.json
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@ customerFormValidation
console.log(validationResult.success); // true
console.log(validationResult.formGlobalErrors); // []
console.log(validationResult.fieldErrors);
/*[
{ succeeded: true, type: "REQUIRED", key: "firstName", errorMessage: "" },
{ succeeded: true, type: "REQUIRED", key: "lastName", errorMessage: "" }
]*/
/*{
firstName: { succeeded: true, type: "REQUIRED", key: "firstName", errorMessage: "" },
lastName: { succeeded: true, type: "REQUIRED", key: "lastName", errorMessage: "" }
}*/
})
.catch((error) => {
// handle unexpected errors
Expand Down Expand Up @@ -240,7 +240,7 @@ testFormValidation
.then((validationResult) => {
console.log(validationResult.succeeded); // true
console.log(validationResult.formGlobalErrors) // []
console.log(validationResult.fieldErrors); // []
console.log(validationResult.fieldErrors); // {}
})
.catch((error) => {
// handle unexpected errors
Expand Down
2 changes: 1 addition & 1 deletion lib/lc-form-validation.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export class FieldValidationResult {

export class FormValidationResult {
succeeded: boolean;
fieldErrors: Array<FieldValidationResult>;
fieldErrors: { [key: string]: FieldValidationResult };
formGlobalErrors: Array<FieldValidationResult>;
}

Expand Down
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.3",
"version": "2.0.0",
"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 @@ -84,6 +84,7 @@
],
"dependencies": {
"es6-promise": "4.1.0",
"lodash.get": "^4.4.2"
"lodash.get": "^4.4.2",
"lodash.set": "^4.3.2"
}
}
4 changes: 2 additions & 2 deletions lib/src/entities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ export class FieldValidationResult {

export class FormValidationResult {
succeeded: boolean;
fieldErrors: FieldValidationResult[];
fieldErrors: { [key: string]: FieldValidationResult };
formGlobalErrors: FieldValidationResult[];

constructor() {
this.succeeded = false;
this.fieldErrors = [];
this.fieldErrors = {};
}
}

Expand Down
284 changes: 168 additions & 116 deletions lib/src/spec/validationEngineValidateForm.spec.ts

Large diffs are not rendered by default.

99 changes: 75 additions & 24 deletions lib/src/spec/validationsResultBuilder.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ describe('ValidationsResultBuilder ', () => {
expect(result.succeeded).to.be.true;
});

it('Spec #8 => should returns new FormValidationResult equals { fieldErrors: [] } ' +
it('Spec #8 => should returns new FormValidationResult equals { fieldErrors: {} } ' +
'when passing fieldValidationResults equals undefined', () => {
//Arrange
let fieldValidationResults = undefined;
Expand All @@ -113,10 +113,10 @@ describe('ValidationsResultBuilder ', () => {
let result = validationsResultBuilder.buildFormValidationsResult(fieldValidationResults);

//Assert
expect(result.fieldErrors).to.be.empty;
expect(result.fieldErrors).to.deep.equals({});
});

it('Spec #9 => should returns new FormValidationResult equals { fieldErrors: [] } ' +
it('Spec #9 => should returns new FormValidationResult equals { fieldErrors: {} } ' +
'when passing fieldValidationResults equals null', () => {
//Arrange
let fieldValidationResults = null;
Expand All @@ -125,10 +125,10 @@ describe('ValidationsResultBuilder ', () => {
let result = validationsResultBuilder.buildFormValidationsResult(fieldValidationResults);

//Assert
expect(result.fieldErrors).to.be.empty;
expect(result.fieldErrors).to.deep.equals({});
});

it('Spec #10 => should returns new FormValidationResult equals { fieldErrors: [] } ' +
it('Spec #10 => should returns new FormValidationResult equals { fieldErrors: {} } ' +
'when passing fieldValidationResults equals empty', () => {
//Arrange
let fieldValidationResults = [];
Expand All @@ -137,11 +137,11 @@ describe('ValidationsResultBuilder ', () => {
let result = validationsResultBuilder.buildFormValidationsResult(fieldValidationResults);

//Assert
expect(result.fieldErrors).to.be.empty;
expect(result.fieldErrors).to.deep.equals({});
});

it('Spec #11 => should returns new FormValidationResult equals ' +
'{ fieldErrors: [{ key: "test" }] } with length equals 1 ' +
'{ fieldErrors: { test: { key: "test", succeeded: false, errorMessage: "", type: "" } } }' +
'when passing fieldValidationResults with one item equals { key: "test" }', () => {
//Arrange
let fieldValidationResult = new FieldValidationResult();
Expand All @@ -152,12 +152,18 @@ describe('ValidationsResultBuilder ', () => {
let result = validationsResultBuilder.buildFormValidationsResult(fieldValidationResults);

//Assert
expect(result.fieldErrors).to.have.length(1);
expect(result.fieldErrors[0].key).to.be.equal('test');
expect(result.fieldErrors).to.deep.equal({
test: {
key: 'test',
succeeded: false,
errorMessage: '',
type: '',
} as FieldValidationResult,
});
});

it('Spec #12 => should returns new FormValidationResult equals ' +
'{ fieldErrors: [] } with length equals 0 ' +
'{ fieldErrors: {} } without properties ' +
'when passing fieldValidationResults with one item equals { key: null }', () => {
//Arrange
let fieldValidationResult = new FieldValidationResult();
Expand All @@ -168,11 +174,11 @@ describe('ValidationsResultBuilder ', () => {
let result = validationsResultBuilder.buildFormValidationsResult(fieldValidationResults);

//Assert
expect(result.fieldErrors).to.have.length(0);
expect(result.fieldErrors).to.deep.equals({});
});

it('Spec #13 => should returns new FormValidationResult equals ' +
'{ fieldErrors: [] } with length equals 0 ' +
'{ fieldErrors: {} } without properties ' +
'when passing fieldValidationResults with one item equals { key: undefined }', () => {
//Arrange
let fieldValidationResult = new FieldValidationResult();
Expand All @@ -183,11 +189,11 @@ describe('ValidationsResultBuilder ', () => {
let result = validationsResultBuilder.buildFormValidationsResult(fieldValidationResults);

//Assert
expect(result.fieldErrors).to.have.length(0);
expect(result.fieldErrors).to.deep.equals({});
});

it('Spec #14 => should returns new FormValidationResult equals ' +
'{ fieldErrors: [] } with length equals 0 ' +
'{ fieldErrors: {} } without properties ' +
'when passing fieldValidationResults with one item equals { key: "" }', () => {
//Arrange
let fieldValidationResult = new FieldValidationResult();
Expand All @@ -198,11 +204,11 @@ describe('ValidationsResultBuilder ', () => {
let result = validationsResultBuilder.buildFormValidationsResult(fieldValidationResults);

//Assert
expect(result.fieldErrors).to.have.length(0);
expect(result.fieldErrors).to.deep.equals({});
});

it('Spec #15 => should returns new FormValidationResult equals ' +
'{ fieldErrors: [] } with length equals 0 ' +
'{ fieldErrors: {} } without properties ' +
'when passing fieldValidationResults with one item equals { key: "_GLOBAL_FORM_" }', () => {
//Arrange
let fieldValidationResult = new FieldValidationResult();
Expand All @@ -213,7 +219,7 @@ describe('ValidationsResultBuilder ', () => {
let result = validationsResultBuilder.buildFormValidationsResult(fieldValidationResults);

//Assert
expect(result.fieldErrors).to.have.length(0);
expect(result.fieldErrors).to.deep.equals({});
});

it('Spec #16 => should returns new FormValidationResult equals ' +
Expand Down Expand Up @@ -296,7 +302,7 @@ describe('ValidationsResultBuilder ', () => {
});

it('Spec #21 => should returns new FormValidationResult equals ' +
'{ fieldErrors: [{ key: "test" }] } with length equals 1 ' +
'{ fieldErrors: { test: { key: "test" } } } ' +
'when passing fieldValidationResults with two item first equals { key: "test" }' +
'and second equals null', () => {
//Arrange
Expand All @@ -311,12 +317,18 @@ describe('ValidationsResultBuilder ', () => {
let result = validationsResultBuilder.buildFormValidationsResult(fieldValidationResults);

//Assert
expect(result.fieldErrors).to.have.length(1);
expect(result.fieldErrors[0].key).to.be.equal('test');
expect(result.fieldErrors).to.deep.equal({
test: {
key: 'test',
succeeded: false,
errorMessage: '',
type: '',
} as FieldValidationResult,
});
});

it('Spec #22 => should returns new FormValidationResult equals ' +
'{ fieldErrors: [{ key: "test" }] } with length equals 1 ' +
'{ fieldErrors: { test: { key: "test" } } } ' +
'when passing fieldValidationResults with two item first equals { key: "test" }' +
'and second equals undefined', () => {
//Arrange
Expand All @@ -331,11 +343,50 @@ describe('ValidationsResultBuilder ', () => {
let result = validationsResultBuilder.buildFormValidationsResult(fieldValidationResults);

//Assert
expect(result.fieldErrors).to.have.length(1);
expect(result.fieldErrors[0].key).to.be.equal('test');
expect(result.fieldErrors).to.deep.equal({
test: {
key: 'test',
succeeded: false,
errorMessage: '',
type: '',
} as FieldValidationResult,
});
});

it('Spec #23 => should returns new FormValidationResult equals ' +
'{ fieldErrors: { test1: { key: "test1" }, test2: { key: "test2" } } } ' +
'when passing fieldValidationResults with two item first equals { key: "test1" }' +
'and second equals { key: "test2" }', () => {
//Arrange
const fieldValidationResult1 = new FieldValidationResult();
fieldValidationResult1.key = 'test1';

const fieldValidationResult2 = new FieldValidationResult();
fieldValidationResult2.key = 'test2';

const fieldValidationResults = [fieldValidationResult1, fieldValidationResult2];

//Act
const result = validationsResultBuilder.buildFormValidationsResult(fieldValidationResults);

//Assert
expect(result.fieldErrors).to.deep.equal({
test1: {
key: 'test1',
succeeded: false,
errorMessage: '',
type: '',
} as FieldValidationResult,
test2: {
key: 'test2',
succeeded: false,
errorMessage: '',
type: '',
} as FieldValidationResult,
});
});

it('Spec #24 => should returns new FormValidationResult equals ' +
'{ formGlobalErrors: [{ key: "_GLOBAL_FORM_" }] } with length equals 1 ' +
'when passing fieldValidationResults with two item first equals { key: "_GLOBAL_FORM_" }' +
'and second equals null', () => {
Expand All @@ -355,7 +406,7 @@ describe('ValidationsResultBuilder ', () => {
expect(result.formGlobalErrors[0].key).to.be.equal('_GLOBAL_FORM_');
});

it('Spec #24 => should returns new FormValidationResult equals ' +
it('Spec #25 => should returns new FormValidationResult equals ' +
'{ formGlobalErrors: [{ key: "_GLOBAL_FORM_" }] } with length equals 1 ' +
'when passing fieldValidationResults with two item first equals { key: "_GLOBAL_FORM_" }' +
'and second equals undefined', () => {
Expand Down
8 changes: 7 additions & 1 deletion lib/src/validationsResultBuilder.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { FieldValidationResult, FormValidationResult } from './entities';
import { consts } from './consts';
import set from 'lodash.set';

export class ValidationsResultBuilder {
buildFormValidationsResult(fieldValidationResults: Array<FieldValidationResult>): FormValidationResult {
Expand All @@ -10,7 +11,8 @@ export class ValidationsResultBuilder {
this.setGlobalKeyToEmptyKeys(filteredFieldValidationResults);

formValidationResult.succeeded = filteredFieldValidationResults.every(fvr => fvr.succeeded);
formValidationResult.fieldErrors = filteredFieldValidationResults.filter(fvr => fvr.key !== consts.globalFormValidationId);
const fieldValidationResultList = filteredFieldValidationResults.filter(fvr => fvr.key !== consts.globalFormValidationId);
formValidationResult.fieldErrors = this.mapFieldValidationResultListToFieldErrorsObject(fieldValidationResultList);
formValidationResult.formGlobalErrors = filteredFieldValidationResults.filter(fvr => fvr.key === consts.globalFormValidationId);
}

Expand All @@ -31,6 +33,10 @@ export class ValidationsResultBuilder {
}
});
}

private mapFieldValidationResultListToFieldErrorsObject = (fieldValidationResultList: FieldValidationResult[]): { [key: string]: FieldValidationResult } => (
fieldValidationResultList.reduce((errors, result) => set(errors, result.key, result), {})
)
}

let validationsResultBuilder = new ValidationsResultBuilder();
Expand Down
5 changes: 3 additions & 2 deletions samples/jquery/00 ShoppingForm/src/modules/app/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import $ from 'jquery';
import { productsService } from '../../services/productsService';
import { productsFormValidation } from './validation/formProductValidationService';

let storedProducts = [];
let $selBrands, $selProducts, $formProducts, $txtNif, $txtDiscount;

class App {
Expand Down Expand Up @@ -94,7 +93,9 @@ class App {
productsFormValidation
.validateForm(vm)
.then(validationResult => {
validationResult.fieldErrors.forEach(this.handleFieldValidationResult($form));
Object.keys(validationResult.fieldErrors).forEach((key) => {
this.handleFieldValidationResult($form)(validationResult.fieldErrors[key]);
});
if (validationResult.succeeded) {
console.log('Form is sent');
}
Expand Down
11 changes: 4 additions & 7 deletions samples/react/es6/00 SimpleForm/src/reducers/customer.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,11 @@ function customerProcessUIInputCompleted(state, action) {
}

function customerSaveCompleted(state, action) {
const newCustomerErrors = { ...state.customerErrors };

action.formValidationResult.fieldErrors.forEach(fieldValidationResult => {
newCustomerErrors[fieldValidationResult.key] = fieldValidationResult;
});

return {
...state,
customerErrors: newCustomerErrors
customerErrors: {
...state.customerErrors,
...action.formValidationResult.fieldErrors,
},
};
}
11 changes: 4 additions & 7 deletions samples/react/es6/01 SignupForm/src/reducers/signup.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,11 @@ function signupProcessCompleted(state, action) {
}

function performSignupCompleted(state, action) {
const newSignupErrors = { ...state.signupErrors };

action.formValidationResult.fieldErrors.forEach(fieldValidationResult => {
newSignupErrors[fieldValidationResult.key] = fieldValidationResult;
});

return {
...state,
signupErrors: newSignupErrors
signupErrors: {
...state.signupErrors,
...action.formValidationResult.fieldErrors,
},
};
}
11 changes: 4 additions & 7 deletions samples/react/typescript/00 SimpleForm/src/reducers/customer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,11 @@ function customerProcessUIInputCompleted(state: CustomerState, action: ICustomer
}

function customerSaveCompleted(state: CustomerState, action: ICustomerSaveCompletedAction): CustomerState {
const newCustomerErrors: CustomerErrors = Object.assign({}, state.customerErrors);

action.formValidationResult.fieldErrors.forEach(fieldValidationResult => {
newCustomerErrors[fieldValidationResult.key] = fieldValidationResult;
});

return {
...state,
customerErrors: newCustomerErrors
customerErrors: {
...state.customerErrors,
...action.formValidationResult.fieldErrors,
}
};
}
3 changes: 2 additions & 1 deletion samples/react/typescript/00 SimpleForm/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"preserveConstEnums": true,
"suppressImplicitAnyIndexErrors": true
"suppressImplicitAnyIndexErrors": true,
"skipLibCheck": true
},
"compileOnSave": false,
"exclude": [
Expand Down
Loading

0 comments on commit 1f44dff

Please sign in to comment.