Skip to content

Commit

Permalink
feat: improve fakes
Browse files Browse the repository at this point in the history
Signed-off-by: hxtree <[email protected]>
  • Loading branch information
hxtree committed Nov 2, 2023
1 parent af39fcf commit a0f2ebf
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 73 deletions.
89 changes: 41 additions & 48 deletions libraries/faker-factory/src/__tests__/get-json-schemas.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,48 @@
// eslint-disable-next-line max-classes-per-file
import { Type } from 'class-transformer';
import { IsLongitude, IsString, ValidateNested } from 'class-validator';
import { IsDiceNotation } from '@cats-cradle/validation-schemas';
import { IsString, ValidateNested } from 'class-validator';
import { getJsonSchemas } from '../get-json-schemas';

describe('getJsonSchemas', () => {
it('should get all schemas', () => {
it.each([
['longitude', 'longitude'],
['latitude', 'latitude'],
['money', 'money'],
])(
'should determine "%s" property to have JSONSchema format "%s"',
async (property: string, value: any) => {
const { SampleClass } = require('./sample-class');
const schemas = getJsonSchemas();
expect(schemas.SampleClass.properties).toHaveProperty(
property,
expect.objectContaining({ format: value, type: 'string' }),
);
},
);

it.each([
['diceNotation', '(\\d+)?d(\\d+)([+-]\\d+)?'],
[
'uuidV4',
'^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[4][0-9a-fA-F]{3}-[89AB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$',
],
])(
'should determine "%s" property to have JSONSchema pattern "%s"',
async (property: string, value: string) => {
const { SampleClass } = require('./sample-class');
const schemas = getJsonSchemas();
expect(schemas.SampleClass.properties).toHaveProperty(property);
expect(schemas.SampleClass.properties).toHaveProperty(
property,
expect.objectContaining({
pattern: value,
type: 'string',
}),
);
},
);

it('should ref ValidateNested schemas', () => {
class BlogPost {
@IsString()
public words: string;
Expand All @@ -17,8 +54,7 @@ describe('getJsonSchemas', () => {
public blogPosts: BlogPost[];
}

const schemas = getJsonSchemas();
expect(schemas).toEqual({
expect(getJsonSchemas()).toMatchObject({
BlogPost: {
properties: { words: { type: 'string' } },
required: ['words'],
Expand All @@ -33,47 +69,4 @@ describe('getJsonSchemas', () => {
},
});
});

it('should get accurate pattern for schemas', async () => {
class TestClass {
@IsDiceNotation()
public property: string;
}
const schemas = getJsonSchemas();

expect(schemas).toMatchObject({
TestClass: {
properties: {
property: {
pattern: /(\d+)?d(\d+)([+-]\d+)?/,
type: 'string',
},
},
type: 'object',
required: ['property'],
},
});
});

it('should get accurate pattern for schemas', async () => {
class Place {
@IsLongitude()
public property: string;
}

const schemas = getJsonSchemas();

expect(schemas).toMatchObject({
Place: {
properties: {
property: {
format: 'longitude',
type: 'string',
},
},
type: 'object',
required: ['property'],
},
});
});
});
16 changes: 16 additions & 0 deletions libraries/faker-factory/src/__tests__/sample-class.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ import {
IsOptional,
Type,
IsLongitude,
IsMoney,
IsDiceNotation,
IsLatitude,
IsUuidV4,
} from '@cats-cradle/validation-schemas';

export enum SampleEnum {
Expand All @@ -42,9 +46,15 @@ export class SampleClass {
@IsNumber()
public number: number;

@IsMoney()
public money: string;

@IsString()
public string: string;

@IsUuidV4()
public uuidV4: string;

@IsUUID()
public uuid: string;

Expand All @@ -57,6 +67,12 @@ export class SampleClass {
@IsLongitude()
public longitude: string;

@IsLatitude()
public latitude: string;

@IsDiceNotation()
public diceNotation: string;

@IsString()
@Length(1, 10)
public min: string;
Expand Down
17 changes: 17 additions & 0 deletions libraries/faker-factory/src/generate-fake-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ import currency from 'currency.js';
import { faker } from '@faker-js/faker';
import { Settings, defaultSettings } from './settings';

/**
* Determines how JSONSchema is faked based on format, pattern, etc.
*
* @param inputSchema
* @param fakerRefs
* @param inputSettings
* @returns
*/
export async function generateFakeData(
inputSchema: any,
fakerRefs: any,
Expand All @@ -24,6 +32,15 @@ export async function generateFakeData(
precision: 2,
}).format());

JSONSchemaFaker.format('money', () =>
// eslint-disable-next-line implicit-arrow-linebreak
currency(faker.finance.amount(), {
symbol: '',
separator: '',
decimal: '.',
precision: 2,
}).format());

JSONSchemaFaker.format('email', () => faker.internet.email().toLowerCase());

JSONSchemaFaker.format('uuid', () => faker.datatype.uuid());
Expand Down
9 changes: 8 additions & 1 deletion libraries/faker-factory/src/get-json-schemas.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import 'reflect-metadata';
import { ValidationTypes } from '@cats-cradle/validation-schemas';
import { validationMetadatasToSchemas } from 'class-validator-jsonschema';
import { defaultMetadataStorage } from 'class-transformer/cjs/storage';
import { SchemasObject } from 'openapi3-ts';

/**
* Determines how JSONSchema is created from validation schema decorators
* @returns
*/
export function getJsonSchemas(): SchemasObject {
return validationMetadatasToSchemas({
refPointerPrefix: '',
Expand All @@ -15,6 +18,10 @@ export function getJsonSchemas(): SchemasObject {
* {@link} https://www.npmjs.com/package/class-validator-jsonschema
*/
additionalConverters: {
isMoney: {
format: 'money',
type: 'string',
},
isLongitude: {
format: 'longitude',
type: 'string',
Expand Down
7 changes: 4 additions & 3 deletions libraries/validation-schemas/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# @cats-cradle/validation-schemas

Contains standard class-validator decorators and custom decorators for use
primarly in defining and validating data used in game design.
primarily in defining and validating data used in game design.

```typescript
import {
Expand All @@ -24,10 +24,11 @@ const errors: ValidationError[] = validateSync(testClass);
console.log(errors.length);
```

All validation decorators should be supported by `@cats-cradle/FakerFactory`
All validation decorators should be supported by
[@cats-cradle/faker-factory](https://www.npmjs.com/package/@cats-cradle/faker-factory)
enabling automatic generation of fakes.

## Documentation
## References

- [validatorjs](https://validatejs.org/)
- [class-validator](https://github.com/typestack/class-validator)
30 changes: 9 additions & 21 deletions libraries/validation-schemas/src/custom/is-uuidv4.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
import { registerDecorator, ValidationOptions } from 'class-validator';
import { Matches, matches, ValidationOptions } from 'class-validator';

export function IsUuidV4Validator(value: any): boolean {
return (
typeof value === 'string' &&
/^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[4][0-9a-fA-F]{3}-[89AB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$/i.test(
value,
)
);
export const UUID_V4_REGEX = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[4][0-9a-fA-F]{3}-[89AB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$/;

export function IsUuidV4Validator(value: string) {
return matches(value, UUID_V4_REGEX);
}

/**
Expand All @@ -18,17 +15,8 @@ export function IsUuidV4Validator(value: any): boolean {
* @param validationOptions
* @returns
*/
export function IsUuidV4(validationOptions?: ValidationOptions) {
return function (object: Object, propertyName: string) {
registerDecorator({
name: 'isUuidV4',
target: object.constructor,
propertyName,
constraints: [],
options: validationOptions,
validator: {
validate: IsUuidV4Validator,
},
});
};
export function IsUuidV4(
validationOptions?: ValidationOptions,
): PropertyDecorator {
return Matches(UUID_V4_REGEX, validationOptions);
}

0 comments on commit a0f2ebf

Please sign in to comment.