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

fix(zod-mock): [#172] enhance mockeryMapper #230

Open
wants to merge 1 commit into
base: main
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
56 changes: 55 additions & 1 deletion packages/zod-mock/src/lib/zod-mock.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { z } from 'zod';
import { generateMock, ZodMockError } from './zod-mock';
import { faker } from '@faker-js/faker';
import { faker, Faker } from '@faker-js/faker';
import { FakerFunction } from './zod-mockery-map';

describe('zod-mock', () => {
it('should generate a mock object using faker', () => {
Expand Down Expand Up @@ -734,4 +735,57 @@ describe('zod-mock', () => {
expect(mockedFlight.operating_airline.departure.time).toBeInstanceOf(Date);
expect(mockedFlight.operating_airline.flightNumber.length).toBeLessThan(5);
});

describe('mockeryMapper', () => {
const quota = z.object({
id: z.number(),
created: z.date(),
territoryName: z.string(),
enabled: z.boolean(),
});

const mockeryMapper = (
keyName: string,
fakerInstance: Faker
): FakerFunction | undefined => {
const keyToFnMap: Record<string, FakerFunction> = {
id: () => fakerInstance.number.int({ min: 3, max: 22 }),
enabled: () => fakerInstance.datatype.boolean({ probability: 1 }),
territoryName: () => fakerInstance.string.fromCharacters('abcdef', 20),
created: () => fakerInstance.date.past(),
};
return keyName && keyName.toLowerCase() in keyToFnMap
? keyToFnMap[keyName.toLowerCase() as never]
: undefined;
};

// generate multiple records to ensure consistency
const mockedQuotas = generateMock(quota.array().length(10), {
mockeryMapper,
});

describe.each(mockedQuotas)(
'%#. quota with id $id mock data unit tests',
(mockedQuota, index) => {
it(`uses the id faker function in the mockeryMapper to generate ${mockedQuota.id}`, () => {
// the value should always be in the range [3, 22] as pert hge mockery mapper function
expect(mockedQuota.id).toBeGreaterThanOrEqual(3);
expect(mockedQuota.id).toBeLessThanOrEqual(22);
});

it(`uses the enabled faker function in the mockeryMapper to generate ${mockedQuota.enabled}`, () => {
// the value should always be true as per the mockery mapper function
expect(mockedQuota.enabled).toBe(true);
});

it(`uses the created faker function in the mockeryMapper to generate ${mockedQuota.created.toISOString()}`, () => {
// the date should always be in the past as per the mockery mapper function
expect(mockedQuota.created).toBeInstanceOf(Date);
expect(mockedQuota.created.getTime()).toBeLessThan(
new Date().getTime()
);
});
}
);
});
});
32 changes: 32 additions & 0 deletions packages/zod-mock/src/lib/zod-mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,21 @@ function findMatchingFaker(
}
}

/**
* Generate mock value from a matching faker function extracted from the mockeryMapper
* @param options mock generator options
* @returns a mock value if a faker function is found in the mockeryMapper passed
*/
function generateMockFromMatchingFaker(options?: GenerateMockOptions) {
// check if there exists a faker for the given key in the mockery mapper
const foundMockeryMapperFaker = options?.keyName
? findMatchingFaker(options?.keyName, options.faker, options.mockeryMapper)
: undefined;

// generate the mock value from the faker function found
return foundMockeryMapperFaker?.() ?? undefined;
}

function parseString(
zodRef: z.ZodString,
options?: GenerateMockOptions
Expand Down Expand Up @@ -265,6 +280,12 @@ function parseString(

function parseBoolean(zodRef: z.ZodBoolean, options?: GenerateMockOptions) {
const fakerInstance = options?.faker || faker;

// generate the mock boolean from the mockery mapper
const mockBoolean = generateMockFromMatchingFaker(options);
// verify that the return type of the mock data is a boolean for it to be acceptable
if (typeof mockBoolean === 'boolean') return mockBoolean;

return fakerInstance.datatype.boolean();
}

Expand All @@ -285,6 +306,11 @@ function parseDate(zodRef: z.ZodDate, options?: GenerateMockOptions) {
}
});

// generate the mock date from the mockery mapper
const mockDate = generateMockFromMatchingFaker(options);
// verify that the return type of the mock data is a valid date for it to be acceptable
if (mockDate instanceof Date) return mockDate;

if (min !== undefined && max !== undefined) {
return fakerInstance.date.between({ from: min, to: max });
} else if (min !== undefined && max === undefined) {
Expand Down Expand Up @@ -316,6 +342,12 @@ function parseNumber(
break;
}
});

// generate the mock number from the mockeryMapper
const mockNumber = generateMockFromMatchingFaker(options);
// verify that the return type of the mock data is a number for it to be acceptable
if (typeof mockNumber === 'number') return mockNumber;

return fakerInstance.number.int(fakerOptions);
}

Expand Down
Loading