From 72e00a845d6e3f27f451cabc58334faffeb57f27 Mon Sep 17 00:00:00 2001 From: Ernest Date: Fri, 3 Jan 2025 23:04:39 +0800 Subject: [PATCH] fix: bigint (#315) --- src/zod-bigint-faker.ts | 38 +++++++++++++++--------------- tests/zod-bigint-faker.test.ts | 43 ++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 19 deletions(-) diff --git a/src/zod-bigint-faker.ts b/src/zod-bigint-faker.ts index f4817ca..1b81853 100644 --- a/src/zod-bigint-faker.ts +++ b/src/zod-bigint-faker.ts @@ -6,7 +6,7 @@ export class ZodBigIntFaker extends ZodTypeFaker { fake(): z.infer { let min: undefined | bigint = undefined let max: undefined | bigint = undefined - let multipleOf: undefined | bigint = undefined + let multipleOf: bigint = 1n for (const check of this.schema._def.checks) { switch (check.kind) { case 'min': @@ -16,31 +16,31 @@ export class ZodBigIntFaker extends ZodTypeFaker { max = check.value - (check.inclusive ? 0n : 1n) break case 'multipleOf': - multipleOf = check.value + multipleOf = check.value < 0n ? -check.value : check.value break default: const _: never = check } } - - // workaround: https://github.com/faker-js/faker/pull/3363 - if (min === undefined && max !== undefined && max < 0n) { - min = max - (multipleOf === undefined ? 1_000n : multipleOf * 1_000n) - } - - if (multipleOf !== undefined) { - if (min !== undefined && max !== undefined) { - return min + runFake(faker => faker.number.bigInt({ min: 0n, max: (max - min) / multipleOf })) * multipleOf - } else if (min !== undefined) { - return min + runFake(faker => faker.number.bigInt({ min: 0n })) * multipleOf - } else if (max !== undefined) { - return max - runFake(faker => faker.number.bigInt({ min: 0n })) * multipleOf - } else { - return runFake(faker => faker.number.bigInt({ min: 0n })) * multipleOf - } + const largeThanMultipleOf = multipleOf === undefined ? 1000n : multipleOf * 1000n + if (min !== undefined && max !== undefined) { + } else if (min !== undefined) { + max = min + largeThanMultipleOf + } else if (max !== undefined) { + min = max - largeThanMultipleOf } else { - return runFake(faker => faker.number.bigInt({ min, max })) + min = -largeThanMultipleOf + max = largeThanMultipleOf } + const data = min + runFake(faker => faker.number.bigInt({ min: 0n, max: (max - min) / multipleOf })) * multipleOf + const remaining = multipleOf - ((data < 0n ? -data : data) % multipleOf) + return data >= 0n + ? data + remaining > max + ? data - (multipleOf - remaining) + : data + remaining + : data - remaining < min + ? data + (multipleOf - remaining) + : data - remaining } static create(schema: z.ZodBigInt): ZodBigIntFaker { diff --git a/tests/zod-bigint-faker.test.ts b/tests/zod-bigint-faker.test.ts index 9072429..bec43f1 100644 --- a/tests/zod-bigint-faker.test.ts +++ b/tests/zod-bigint-faker.test.ts @@ -228,4 +228,47 @@ describe('edge case', () => { const data = faker.fake() expect(schema.safeParse(data).success).toBe(true) }) + + test('multiplyOf', () => { + for (let i = 0n; i < 2000n; i++) { + const schema = z + .bigint() + .multipleOf(37n) + .min(i) + .max(i + 37n) + const faker = zodBigIntFaker(schema) + const data = faker.fake() + expect(schema.safeParse(data).success).toBe(true) + } + for (let i = 0n; i > -2000n; i--) { + const schema = z + .bigint() + .multipleOf(37n) + .min(i - 37n) + .max(i) + const faker = zodBigIntFaker(schema) + const data = faker.fake() + expect(schema.safeParse(data).success).toBe(true) + } + for (let i = 0n; i < 2000n; i++) { + const schema = z + .bigint() + .multipleOf(-37n) + .min(i) + .max(i + 37n) + const faker = zodBigIntFaker(schema) + const data = faker.fake() + expect(schema.safeParse(data).success).toBe(true) + } + for (let i = 0n; i > -2000n; i--) { + const schema = z + .bigint() + .multipleOf(-37n) + .min(i - 37n) + .max(i) + const faker = zodBigIntFaker(schema) + const data = faker.fake() + expect(schema.safeParse(data).success).toBe(true) + } + }) })