Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PN-7276 - Add required rule on pn-validator #1256

Merged
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
24 changes: 12 additions & 12 deletions packages/pn-validator/src/ValidatorBuilder.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import { IsArray } from './rules/IsArray';
import { IsObject } from './rules/IsObject';
import { IsDate } from './rules/IsDate';
import { IsString } from './rules/IsString';
import { IsNumber } from './rules/IsNumber';
import { ValidationResult } from './types/ValidationResult';
import { TypeRules } from './types/TypeRules';
import { hasError } from './HasError';
import { Rule } from './Rule';
import { ArrayRuleValidator } from './ruleValidators/ArrayRuleValidator';
import { BooleanRuleValidator } from './ruleValidators/BooleanRuleValidator';
import { StringRuleValidator } from './ruleValidators/StringRuleValidator';
import { NumberRuleValidator } from './ruleValidators/NumberRuleValidator';
import { DateRuleValidator } from './ruleValidators/DateRuleValidator';
import { NumberRuleValidator } from './ruleValidators/NumberRuleValidator';
import { ObjectRuleValidator } from './ruleValidators/ObjectRuleValidator';
import { ArrayRuleValidator } from './ruleValidators/ArrayRuleValidator';
import { hasError } from './HasError';
import { Rule } from './Rule';
import { StringRuleValidator } from './ruleValidators/StringRuleValidator';
import { IsArray } from './rules/IsArray';
import { IsBoolean } from './rules/IsBoolean';
import { IsDate } from './rules/IsDate';
import { IsNumber } from './rules/IsNumber';
import { IsObject } from './rules/IsObject';
import { IsString } from './rules/IsString';
import { TypeRules } from './types/TypeRules';
import { ValidationResult } from './types/ValidationResult';

export class ValidatorBuilder<TModel, TValue> {
private rules: Array<{ isAsync: boolean; rule: Rule<TModel, TValue> }> = [];
Expand Down
2 changes: 2 additions & 0 deletions packages/pn-validator/src/__test__/ValidatorBuilder.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ const checkCommonRules = (rules: any) => {
expect(rules.isOneOf).toBeDefined();
expect(rules.customValidator).toBeDefined();
expect(rules.not).toBeDefined();
expect(rules.isRequired).toBeDefined();
expect(rules.not().isNull).toBeDefined();
expect(rules.not().isUndefined).toBeDefined();
expect(rules.not().isEqual).toBeDefined();
expect(rules.not().isOneOf).toBeDefined();
expect(rules.not().isRequired).toBeDefined();
};

describe('Test ValidatorBuilder', () => {
Expand Down
26 changes: 20 additions & 6 deletions packages/pn-validator/src/ruleValidators/CommonRuleValidator.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { NotRuleValidator } from '../types/CommonRules';
import { IsEqual } from '../rules/IsEqual';
import { IsNull } from '../rules/IsNull';
import { IsUndefined } from '../rules/IsUndefined';
import { Rule } from '../Rule';
// import { IsEmpty } from '../rules/IsEmpty';
import { CustomValidator } from '../rules/CustomValidator';
import { ValidationResult } from '../types/ValidationResult';
import { Rule } from '../Rule';
import { IsEqual } from '../rules/IsEqual';
import { IsNull } from '../rules/IsNull';
// import { Matches } from '../rules/Matches';
import { IsOneOf } from '../rules/IsOneOf';
import { IsUndefined } from '../rules/IsUndefined';
import { Required } from '../rules/Required';
import { NotRuleValidator } from '../types/CommonRules';
import { ValidationResult } from '../types/ValidationResult';

export abstract class CommonRuleValidator<TModel, TValue> {
protected pushRule: (rule: Rule<TModel, TValue>) => void;
Expand All @@ -31,6 +32,11 @@ export abstract class CommonRuleValidator<TModel, TValue> {
return this;
};

private addRequiredRule = (customErrorMessage?: string) => {
this.pushRule(new Required<TModel, TValue>(customErrorMessage));
return this;
};

private addIsOneOfRule = (
possibleValues: Array<TValue>,
not: boolean,
Expand Down Expand Up @@ -81,6 +87,13 @@ export abstract class CommonRuleValidator<TModel, TValue> {
return this;
};

/**
* Required
* @param {string} [customErrorMessage] custom message to show when validation fails
*/
public readonly isRequired = (customErrorMessage?: string) =>
this.addRequiredRule(customErrorMessage);
AndreaCimini90 marked this conversation as resolved.
Show resolved Hide resolved

/**
* Negate next rule
*/
Expand All @@ -93,5 +106,6 @@ export abstract class CommonRuleValidator<TModel, TValue> {
this.addIsEqualRule(value, true, customErrorMessage),
isOneOf: (possibleValues: Array<TValue>, customErrorMessage?: string) =>
this.addIsOneOfRule(possibleValues, true, customErrorMessage),
isRequired: (customErrorMessage?: string) => this.addRequiredRule(customErrorMessage),
} as unknown as NotRuleValidator<TModel, TValue>);
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { vi } from 'vitest';

import { ForEachElement } from '../../rules/ForEachElement';
import { IsEmpty } from '../../rules/IsEmpty';
import { ArrayRuleValidator } from '../ArrayRuleValidator';
Expand All @@ -7,15 +8,15 @@ const pushRuleMk = vi.fn();
const dummyRuleValidator = new ArrayRuleValidator(pushRuleMk);

vi.mock('../../rules/IsEmpty', () => {
return {
IsEmpty: vi.fn()
}
return {
IsEmpty: vi.fn(),
};
});

vi.mock('../../rules/ForEachElement', () => {
return {
ForEachElement: vi.fn()
}
return {
ForEachElement: vi.fn(),
};
});

describe('Test ArrayRuleValidator', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,44 +1,52 @@
import { vi } from 'vitest';
import { IsEqual } from './../../rules/IsEqual';

import { CustomValidator } from '../../rules/CustomValidator';
import { IsNull } from '../../rules/IsNull';
import { IsUndefined } from '../../rules/IsUndefined';
import { IsOneOf } from '../../rules/IsOneOf';
import { CustomValidator } from '../../rules/CustomValidator';
import { IsUndefined } from '../../rules/IsUndefined';
import { Required } from '../../rules/Required';
import { CommonRuleValidator } from '../CommonRuleValidator';
import { IsEqual } from './../../rules/IsEqual';

class DummyRuleValidator<TModel, TValue> extends CommonRuleValidator<TModel, TValue> {}

const pushRuleMk = vi.fn();
const dummyRuleValidator = new DummyRuleValidator(pushRuleMk);

vi.mock('../../rules/IsNull', () => {
return {
IsNull: vi.fn()
}
return {
IsNull: vi.fn(),
};
});

vi.mock('../../rules/IsUndefined', () => {
return {
IsUndefined: vi.fn()
}
return {
IsUndefined: vi.fn(),
};
});

vi.mock('../../rules/IsEqual', () => {
return {
IsEqual: vi.fn()
}
return {
IsEqual: vi.fn(),
};
});

vi.mock('../../rules/CustomValidator', () => {
return {
CustomValidator: vi.fn()
}
return {
CustomValidator: vi.fn(),
};
});

vi.mock('../../rules/IsOneOf', () => {
return {
IsOneOf: vi.fn()
}
IsOneOf: vi.fn(),
};
});

vi.mock('../../rules/Required', () => {
return {
Required: vi.fn(),
};
});

describe('Test CommonRuleValidator', () => {
Expand All @@ -52,6 +60,7 @@ describe('Test CommonRuleValidator', () => {
expect(dummyRuleValidator.isUndefined).toBeDefined();
expect(dummyRuleValidator.isEqual).toBeDefined();
expect(dummyRuleValidator.customValidator).toBeDefined();
expect(dummyRuleValidator.isRequired).toBeDefined();
});

it('check if isNull rule is instantiated', () => {
Expand Down Expand Up @@ -89,4 +98,11 @@ describe('Test CommonRuleValidator', () => {
expect(pushRuleMk).toBeCalledWith(new CustomValidator(() => null));
expect(result).toBeInstanceOf(DummyRuleValidator);
});

it('check if required rule is instantiated', () => {
const result = dummyRuleValidator.isRequired();
expect(pushRuleMk).toBeCalledTimes(1);
expect(pushRuleMk).toBeCalledWith(new Required());
expect(result).toBeInstanceOf(DummyRuleValidator);
});
});
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { vi } from 'vitest';

import { GreaterThan } from '../../rules/GreaterThan';
import { LessThan } from '../../rules/LessThan';
import { DateRuleValidator } from '../DateRuleValidator';
Expand All @@ -7,15 +8,15 @@ const pushRuleMk = vi.fn();
const dummyRuleValidator = new DateRuleValidator(pushRuleMk);

vi.mock('../../rules/LessThan', () => {
return {
LessThan: vi.fn()
}
return {
LessThan: vi.fn(),
};
});

vi.mock('../../rules/GreaterThan', () => {
return {
GreaterThan: vi.fn()
}
return {
GreaterThan: vi.fn(),
};
});

describe('Test DateRuleValidator', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { vi } from 'vitest';

import { Between } from '../../rules/Between';
import { GreaterThan } from '../../rules/GreaterThan';
import { LessThan } from '../../rules/LessThan';
Expand All @@ -8,21 +9,21 @@ const pushRuleMk = vi.fn();
const dummyRuleValidator = new NumberRuleValidator(pushRuleMk);

vi.mock('../../rules/LessThan', () => {
return {
LessThan: vi.fn()
}
return {
LessThan: vi.fn(),
};
});

vi.mock('../../rules/GreaterThan', () => {
return {
GreaterThan: vi.fn()
}
return {
GreaterThan: vi.fn(),
};
});

vi.mock('../../rules/Between', () => {
return {
Between: vi.fn()
}
return {
Between: vi.fn(),
};
});

describe('Test NumberRuleValidator', () => {
Expand Down Expand Up @@ -50,7 +51,7 @@ describe('Test NumberRuleValidator', () => {
expect(pushRuleMk).toBeCalledWith(new GreaterThan(1));
expect(result).toBeInstanceOf(NumberRuleValidator);
});

it('check if between rule is instantiated', () => {
const result = dummyRuleValidator.between(1, 2);
expect(pushRuleMk).toBeCalledTimes(1);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { vi } from 'vitest';

import { Validator } from '../../Validator';
import { IsEmpty } from '../../rules/IsEmpty';
import { InnerValidator } from '../../rules/InnerValidator';
import { IsEmpty } from '../../rules/IsEmpty';
import { ObjectRuleValidator } from '../ObjectRuleValidator';

class DummyValidator extends Validator<any> {}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { vi } from 'vitest';

import { IsEmpty } from '../../rules/IsEmpty';
import { Length } from '../../rules/Length';
import { Matches } from '../../rules/Matches';
Expand Down
15 changes: 15 additions & 0 deletions packages/pn-validator/src/rules/Required.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Rule } from '../Rule';
import { isDefined } from '../utility/IsDefined';

export class Required<TModel, TValue> extends Rule<TModel, TValue> {
constructor(customErrorMessage?: string) {
super(customErrorMessage);
}

public valueValidator = (value: TValue) => {
if (!isDefined(value)) {
return 'Value is required';
}
return null;
};
}
21 changes: 21 additions & 0 deletions packages/pn-validator/src/rules/__test__/Required.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Required } from '../Required';

describe('Test required rule', () => {
it('value is undefined', () => {
const rule = new Required();
const result = rule.valueValidator(undefined);
expect(result).toBe('Value is required');
});

it('value is null', () => {
const rule = new Required();
const result = rule.valueValidator(null);
expect(result).toBe('Value is required');
});

it('value is defined', () => {
const rule = new Required();
const result = rule.valueValidator(1);
expect(result).toBe(null);
});
});
4 changes: 1 addition & 3 deletions packages/pn-validator/src/utility/IsDefined.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
export const isDefined = (value: unknown): boolean => {
return value !== null && value !== undefined;
};
export const isDefined = (value: unknown): boolean => value !== null && value !== undefined;