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

[zod-mock] Generate all Dates in a stable way #196

Open
dietrich-iti opened this issue Apr 2, 2024 · 2 comments
Open

[zod-mock] Generate all Dates in a stable way #196

dietrich-iti opened this issue Apr 2, 2024 · 2 comments

Comments

@dietrich-iti
Copy link

dietrich-iti commented Apr 2, 2024

When I generateMock with a provided seed option, I want to get the exact same result every time. However, if my schema contains ZodDate elements without a min or a max, I will get different values on subsequent runs.

Cause of the problem

Mock Date values are generated different ways depending whether they have min and/or max constraints (see parseDate in zod-mock.ts). Three of the cases will generate stable dates given the same random seed, but not the case when neither constraint is set. In this case, it simply calls faker.date.soon(), which will add a random (seed-based) offset to the current time. The current time, of course, will change from one run to the next.

Possible fixes

  1. Send an arbitrary (but constant) refDate to soon() in the !min && !max case. This could be done either universally, or only when the user provides their own random seed.
  2. Expose the refDate option as one of the zod-mock options, and document that users should set it to a fixed value when providing their own random seed.

Example

(using Node REPL, edited for clarity)

> const { z } = await import('zod')
> const { generateMock } = await import('@anatine/zod-mock')

> const dateMinMax = z.date().min(new Date('01/01/2023')).max(new Date('01/01/2024'))
> const dateMin = z.date().min(new Date('01/01/2023'))
> const dateMax = z.date().max(new Date('01/01/2024'))
> const dateUnbound = z.date()

> generateMock(dateMinMax, { seed: 123 })
2023-01-20T02:42:18.434Z
> generateMock(dateMinMax, { seed: 123 })
2023-01-20T02:42:18.434Z

> generateMock(dateMin, { seed: 123 })
2023-01-01T01:15:25.162Z
> generateMock(dateMin, { seed: 123 })
2023-01-01T01:15:25.162Z

> generateMock(dateMax, { seed: 123 })
2023-12-31T22:44:34.838Z
> generateMock(dateMax, { seed: 123 })
2023-12-31T22:44:34.838Z

> generateMock(dateUnbound, { seed: 123 })
2024-04-03T00:59:28.801Z
> generateMock(dateUnbound, { seed: 123 })
2024-04-03T00:59:30.597Z
@ColinCee
Copy link

Also having this issue, I looked into this and it seems the root cause is the config of faker. It's not immediately clear that setting a seed doesn't affect certain date functions

See issues:

Forunately as a result of the issues, the docs have been updated see: https://next.fakerjs.dev/guide/usage.html#reproducible-results

There are a few methods which use relative dates for which setting a random seed is not sufficient to have reproducible results, for example: faker.date.past, faker.date.future, faker.date.birthdate, faker.date.recent, faker.date.soon and faker.git.commitEntry. This is because these methods default to creating a date before or after "today", and "today" depends on when the code is run. To fix this, you can specify a fixed reference date as a Date or string, for example:
// creates a date soon after 2023-01-01
faker.date.soon({ refDate: '2023-01-01T00:00:00.000Z' });
or alternatively you can set a default reference date for all these methods:
// affects all future faker.date.* calls
faker.setDefaultRefDate('2023-01-01T00:00:00.000Z');

Most likely we want to mirror faker's api so we should expose defaultRefDate in the generateMock options and use faker.setDefaultRefDate

@ColinCee
Copy link

To get around the current issue you can pass in an instance of faker

import { faker } from '@faker-js/faker';

faker.seed(123);
faker.setDefaultRefDate(new Date('2023-01-01'));

generateMock(SomeSchema, { faker });

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants