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

add ArraySize Decorator #2513

Open
wants to merge 3 commits into
base: develop
Choose a base branch
from
Open
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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -907,6 +907,7 @@ isBoolean(value);
| `@ArrayNotEmpty()` | Checks if given array is not empty. |
| `@ArrayMinSize(min: number)` | Checks if the array's length is greater than or equal to the specified number. |
| `@ArrayMaxSize(max: number)` | Checks if the array's length is less or equal to the specified number. |
| `@ArraySize(size: number)` | Checks if the array's length is equal to the specified number. |
| `@ArrayUnique(identifier?: (o) => any)` | Checks if all array's values are unique. Comparison for objects is reference-based. Optional function can be speciefied which return value will be used for the comparsion. |
| **Object validation decorators** |
| `@IsInstance(value: any)` | Checks if the property is an instance of the passed value. |
Expand Down
33 changes: 33 additions & 0 deletions src/decorator/array/ArraySize.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { ValidationOptions } from '../ValidationOptions';
import { buildMessage, ValidateBy } from '../common/ValidateBy';

export const ARRAY_SIZE = 'arraySize';

/**
* Checks if the array's length is equal to the specified number.
* If null or undefined is given then this function returns false.
*/
export function arraySize(array: unknown, size: number): boolean {
return Array.isArray(array) && array.length === size;
}

/**
* Checks if the array's length is equal to the specified number.
* If null or undefined is given then this function returns false.
*/
export function ArraySize(size: number, validationOptions?: ValidationOptions): PropertyDecorator {
return ValidateBy(
{
name: ARRAY_SIZE,
constraints: [size],
validator: {
validate: (value, args): boolean => arraySize(value, args?.constraints[0]),
defaultMessage: buildMessage(
eachPrefix => eachPrefix + '$property must contain exactly $constraint1 elements',
validationOptions
),
},
},
validationOptions
);
}
1 change: 1 addition & 0 deletions src/decorator/decorators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ export * from './array/ArrayNotEmpty';
export * from './array/ArrayMinSize';
export * from './array/ArrayMaxSize';
export * from './array/ArrayUnique';
export * from './array/ArraySize';

// -------------------------------------------------------------------------
// Object checkers
Expand Down
35 changes: 35 additions & 0 deletions test/functional/validation-functions-and-decorators.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,8 @@ import {
isTaxId,
IsTaxId,
IsISO4217CurrencyCode,
ArraySize,
arraySize,
} from '../../src/decorator/decorators';
import { Validator } from '../../src/validation/Validator';
import { ValidatorOptions } from '../../src/validation/ValidatorOptions';
Expand Down Expand Up @@ -4523,6 +4525,39 @@ describe('ArrayMaxSize', () => {
});
});

describe('ArraySize', () => {
const constraint = 2;
const validValues = [['world', 'hello']];
const invalidValues = [null, undefined, ['hi', 'typescript', 'javascript'], { test: 'me' }];

class MyClass {
@ArraySize(constraint)
someProperty: string;
}

it('should not fail if validator.validate said that its valid', () => {
return checkValidValues(new MyClass(), validValues);
});

it('should fail if validator.validate said that its invalid', () => {
return checkInvalidValues(new MyClass(), invalidValues);
});

it('should not fail if method in validator said that its valid', () => {
validValues.forEach(value => expect(arraySize(value, constraint)).toBeTruthy());
});

it('should fail if method in validator said that its invalid', () => {
invalidValues.forEach(value => expect(arraySize(value, constraint)).toBeFalsy());
});

it('should return error object with proper data', () => {
const validationType = 'arraySize';
const message = 'someProperty must contain exactly ' + constraintToString(constraint) + ' elements';
return checkReturnedError(new MyClass(), invalidValues, validationType, message);
});
});

describe('ArrayUnique', () => {
const validValues = [
['world', 'hello', 'superman'],
Expand Down