Skip to content

Commit

Permalink
Updated object validator interface.
Browse files Browse the repository at this point in the history
  • Loading branch information
Andrei15193 committed Oct 8, 2024
1 parent 12b21d6 commit 859f338
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 81 deletions.
16 changes: 7 additions & 9 deletions src/forms/FormField.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,15 +123,13 @@ export class FormField<TValue, TValidationError = string> extends Validatable<TV
this._value = value;
this._initialValue = initialValue;

this.validation = validators.reduce(
(objectValidator, validator) => objectValidator.add(validator),
new ObjectValidator<this, TValidationError>({
target: this,
shouldTargetTriggerValidation: (_, changedProperties) => {
return this.onShouldTriggerValidation(changedProperties);
}
})
);
this.validation = new ObjectValidator<this, TValidationError>({
target: this,
shouldTargetTriggerValidation: (_, changedProperties) => {
return this.onShouldTriggerValidation(changedProperties);
}
})
this.validation.add.apply(this.validation, validators);

resolveAllValidationTriggers(validationTriggers).forEach(this.validation.triggers.add, this.validation.triggers);
}
Expand Down
2 changes: 1 addition & 1 deletion src/forms/__tests__/Form.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ describe('Form', (): void => {
let sectionSetupInvocationCount = 0;

const form = new TestForm();
form.validation.add(() => 'error', [form]);
form.validation.add(() => 'error').triggers.add(form);
const field = new FormField({ name: 'field', initialValue: null });
field.reset = () => { fieldResetInvocationCount++; };
form.withFields(field);
Expand Down
105 changes: 55 additions & 50 deletions src/validation/__tests__/ObjectValidator.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,13 +94,13 @@ describe('ObjectValidator', () => {
const viewModelValidationTrigger = new FakeValidatable();

const objectValidator = new ObjectValidator({ target: validatable });
objectValidator.add(
() => {
objectValidator
.add(() => {
invocationCount++;
return 'test error';
},
[viewModelValidationTrigger]
);
})
.triggers
.add(viewModelValidationTrigger);
viewModelValidationTrigger.notifyPropertiesChanged();

expect(invocationCount).toBe(2);
Expand All @@ -113,13 +113,13 @@ describe('ObjectValidator', () => {
const observableCollectionValidationTrigger = new ObservableCollection<number>();

const objectValidator = new ObjectValidator({ target: validatable });
objectValidator.add(
() => {
objectValidator
.add(() => {
invocationCount++;
return 'test error';
},
[observableCollectionValidationTrigger]
);
})
.triggers
.add(observableCollectionValidationTrigger);
observableCollectionValidationTrigger.push(1);

expect(invocationCount).toBe(2);
Expand All @@ -132,13 +132,13 @@ describe('ObjectValidator', () => {
const observableCollectionValidationTrigger = new ObservableCollection<number>([1, 2]);

const objectValidator = new ObjectValidator({ target: validatable });
objectValidator.add(
() => {
objectValidator
.add(() => {
invocationCount++;
return 'test error';
},
[observableCollectionValidationTrigger]
);
})
.triggers
.add(observableCollectionValidationTrigger);
observableCollectionValidationTrigger.reverse();

expect(invocationCount).toBe(2);
Expand All @@ -151,13 +151,13 @@ describe('ObjectValidator', () => {
const observableSetValidationTrigger = new ObservableSet<number>();

const objectValidator = new ObjectValidator({ target: validatable });
objectValidator.add(
() => {
objectValidator
.add(() => {
invocationCount++;
return 'test error';
},
[observableSetValidationTrigger]
);
})
.triggers
.add(observableSetValidationTrigger);
observableSetValidationTrigger.add(1);

expect(invocationCount).toBe(2);
Expand All @@ -170,13 +170,13 @@ describe('ObjectValidator', () => {
const observableMapValidationTrigger = new ObservableMap<number, string>();

const objectValidator = new ObjectValidator({ target: validatable });
objectValidator.add(
() => {
objectValidator
.add(() => {
invocationCount++;
return 'test error';
},
[observableMapValidationTrigger]
);
})
.triggers
.add(observableMapValidationTrigger);
observableMapValidationTrigger.set(1, 'a');

expect(invocationCount).toBe(2);
Expand All @@ -190,13 +190,13 @@ describe('ObjectValidator', () => {
const observableCollection = new ObservableCollection<FakeValidatable>([item]);

const objectValidator = new ObjectValidator({ target: validatable });
objectValidator.add(
() => {
objectValidator
.add(() => {
invocationCount++;
return 'test error';
},
[[observableCollection, item => [item]]]
);
})
.triggers
.add([observableCollection, item => [item]]);

item.notifyPropertiesChanged();

Expand All @@ -211,13 +211,13 @@ describe('ObjectValidator', () => {
const observableSet = new ObservableSet<FakeValidatable>([item]);

const objectValidator = new ObjectValidator({ target: validatable });
objectValidator.add(
() => {
objectValidator
.add(() => {
invocationCount++;
return 'test error';
},
[[observableSet, item => [item]]]
);
})
.triggers
.add([observableSet, item => [item]]);

item.notifyPropertiesChanged();

Expand All @@ -232,13 +232,13 @@ describe('ObjectValidator', () => {
const observableMap = new ObservableMap<number, FakeValidatable>([[1, item]]);

const objectValidator = new ObjectValidator({ target: validatable });
objectValidator.add(
() => {
objectValidator
.add(() => {
invocationCount++;
return 'test error';
},
[[observableMap, item => [item]]]
);
})
.triggers
.add([observableMap, item => [item]]);

item.notifyPropertiesChanged();

Expand All @@ -257,12 +257,17 @@ describe('ObjectValidator', () => {
objectValidator
.add(
() => 'test error 1',
[viewModelValidationTrigger, observableCollectionValidationTrigger, observableSetValidationTrigger, observableMapValidationTrigger]
)
.add(
() => 'test error 2',
[viewModelValidationTrigger, observableCollectionValidationTrigger, observableSetValidationTrigger, observableMapValidationTrigger]
);
)
.triggers
.add(viewModelValidationTrigger)
.add(observableCollectionValidationTrigger)
.add(observableSetValidationTrigger)
.add(observableMapValidationTrigger)
.add(viewModelValidationTrigger)
.add(observableCollectionValidationTrigger)
.add(observableSetValidationTrigger)
.add(observableMapValidationTrigger);

expect(objectValidator.triggers.size).toBe(4);
expect(objectValidator.triggers).toContain(viewModelValidationTrigger);
Expand All @@ -277,13 +282,13 @@ describe('ObjectValidator', () => {
const viewModelValidationTrigger = new FakeValidatable();

const objectValidator = new ObjectValidator({ target: validatable });
objectValidator.add(
() => {
objectValidator
.add(() => {
invocationCount++;
return 'test error 1';
},
[viewModelValidationTrigger]
);
})
.triggers
.add(viewModelValidationTrigger);

objectValidator.triggers.clear();
viewModelValidationTrigger.notifyPropertiesChanged();
Expand Down
7 changes: 3 additions & 4 deletions src/validation/objectValidator/IObjectValidator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,11 @@ export interface IObjectValidator<TValidatable extends IValidatable<TValidationE
readonly triggers: IValidationTriggersSet;

/**
* Configures the given validator and configures the provided triggers.
* @param validator The validators to add.
* @param triggers The triggers for which a validation should occur.
* Configures the given validators and validates the target afterwards.
* @param validators The validators to add.
* @returns Returns the current object validator.
*/
add<TKey = unknown, TItem = unknown>(validator: IValidator<TValidatable, TValidationError> | ValidatorCallback<TValidatable, TValidationError>, triggers?: readonly (WellKnownValidationTrigger<TKey, TItem> | ValidationTrigger)[]): this;
add(...validators: readonly (IValidator<TValidatable, TValidationError> | ValidatorCallback<TValidatable, TValidationError>)[]): this;

/**
* Resets the validator configuraiton, removes all triggers and validators and sets the error on the target to `null`.
Expand Down
32 changes: 15 additions & 17 deletions src/validation/objectValidator/ObjectValidator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ import type { INotifyPropertiesChanged } from '../../viewModels';
import { type IObservableCollection, type IObservableSet, ObservableCollection, ObservableSet } from '../../collections';
import { ViewModelChangedValidationTrigger, resolveValidationTriggers } from '../triggers';

/**
* Represents the object validator configuration.
*/
export interface IObjectValidatorConfig<TValidatable extends IValidatable<TValidationError> & INotifyPropertiesChanged, TValidationError = string> {
readonly target: TValidatable;

Expand Down Expand Up @@ -99,25 +102,20 @@ export class ObjectValidator<TValidatable extends IValidatable<TValidationError>
public readonly triggers: IValidationTriggersSet;

/**
* Configures the given validator and configures the provided triggers.
* @param validator The validators to add.
* @param triggers The triggers for which a validation should occur.
* Configures the given validators and validates the target afterwards.
* @param validators The validators to add.
* @returns Returns the current object validator.
*/
public add<TKey = unknown, TItem = unknown>(validator: IValidator<TValidatable, TValidationError> | ValidatorCallback<TValidatable, TValidationError>, triggers?: readonly (WellKnownValidationTrigger<TKey, TItem> | ValidationTrigger)[]): this {
if (triggers !== null && triggers !== undefined)
triggers.forEach(this.triggers.add, this.triggers);

if (validator !== null && validator !== undefined)
switch (typeof validator) {
case 'function':
this.validators.push({ validate: validator });
break;

case 'object':
this.validators.push(validator);
break;
}
public add(...validators: readonly (IValidator<TValidatable, TValidationError> | ValidatorCallback<TValidatable, TValidationError>)[]): this {
if (validators !== null && validators !== undefined && Array.isArray(validators))
this.validators.push(...validators.map(validator => {
if (typeof validator === 'function')
return {
validate: validator
};
else
return validator;
}));

return this;
}
Expand Down

0 comments on commit 859f338

Please sign in to comment.