From 4732879b2bf81d7960df435cfb22a4a32eaa028c Mon Sep 17 00:00:00 2001 From: Jonas Auer Date: Wed, 19 Oct 2022 14:51:40 +0200 Subject: [PATCH] fix(client): Serialize all Floats in exponential notation (#15879) * test(client): unit test for #12651 * test(client): integration test for #12651 * fix(client): Serialize all floats in exponential notation Fix #12651, fix #13317 * test(internals): Fix normalizeMigrateTimestamps applying to all long numbers * test(client): Convert large-floats tests to functional * test(client): Revert snapshot serializer changes It does not seem that it was indendened for snapshot serizier to apply to select.test.ts. Instead, we are fixing the failure by changing the number so it won't be replaced by serializer. * Revert "test(client): Revert snapshot serializer changes" This reverts commit 7756be2edd37d48ab8c00e612c9e9190092184f1. * Update packages/internals/src/utils/jestSnapshotSerializer.js Co-authored-by: Sergey Tatarintsev Co-authored-by: Alexey Orlenko --- .../__snapshots__/select.test.ts.snap | 6 +- .../__tests__/atomicOperationsUpdate.test.ts | 2 +- .../client/src/__tests__/query/floats.test.ts | 82 +++++++++++++++++++ .../src/__tests__/scalarListCreate.test.ts | 4 +- packages/client/src/runtime/query.ts | 4 + .../tests/functional/large-floats/_matrix.ts | 24 ++++++ .../functional/large-floats/prisma/_schema.ts | 20 +++++ .../tests/functional/large-floats/tests.ts | 32 ++++++++ .../src/utils/jestSnapshotSerializer.js | 2 +- 9 files changed, 169 insertions(+), 7 deletions(-) create mode 100644 packages/client/src/__tests__/query/floats.test.ts create mode 100644 packages/client/tests/functional/large-floats/_matrix.ts create mode 100644 packages/client/tests/functional/large-floats/prisma/_schema.ts create mode 100644 packages/client/tests/functional/large-floats/tests.ts diff --git a/packages/client/src/__tests__/__snapshots__/select.test.ts.snap b/packages/client/src/__tests__/__snapshots__/select.test.ts.snap index f1ab71659641..17e56b71ea19 100644 --- a/packages/client/src/__tests__/__snapshots__/select.test.ts.snap +++ b/packages/client/src/__tests__/__snapshots__/select.test.ts.snap @@ -476,7 +476,7 @@ query { age_gt: 10123123123 id_endsWith: "veryLongNameGoIntoaNewLineNow@gmail.com" name_contains: "hans" - name_gt: 2020123100000023 + name_gt: 2131203912039123 name_in: ["hans"] AND: [ { @@ -541,7 +541,7 @@ Invalid \`prisma.findManyUser()\` invocation: ~~~~~~~~~~~ name_contains: 'hans', ~~~~~~~~~~~~~ - name_gt: 2020123100000023, + name_gt: 2131203912039123, ~~~~~~~ name_in: [ ~~~~~~~ @@ -827,7 +827,7 @@ Invalid \`prisma.findManyUser()\` invocation: ~~~~~~~~~~~ name_contains: 'hans', ~~~~~~~~~~~~~ - name_gt: 2020123100000023, + name_gt: 2131203912039123, ~~~~~~~ name_in: [ ~~~~~~~ diff --git a/packages/client/src/__tests__/atomicOperationsUpdate.test.ts b/packages/client/src/__tests__/atomicOperationsUpdate.test.ts index 64f03505e008..31efda58b9d2 100644 --- a/packages/client/src/__tests__/atomicOperationsUpdate.test.ts +++ b/packages/client/src/__tests__/atomicOperationsUpdate.test.ts @@ -40,7 +40,7 @@ describe('minimal atomic update transformation', () => { mutation { updateOneUser( data: { - countFloat: 3.1415926 + countFloat: 3.1415926e+0 countInt1: 3 } ) { diff --git a/packages/client/src/__tests__/query/floats.test.ts b/packages/client/src/__tests__/query/floats.test.ts new file mode 100644 index 000000000000..3fce9d6d2a8a --- /dev/null +++ b/packages/client/src/__tests__/query/floats.test.ts @@ -0,0 +1,82 @@ +import { getDMMF } from '../../generation/getDMMF' +import { DMMFClass, makeDocument, transformDocument } from '../../runtime' + +const datamodel = /* Prisma */ ` + datasource my_db { + provider = "postgres" + url = env("POSTGRES_URL") + } + + model Floats { + id Int @id + value Float + } +` + +let dmmf + +function getTransformedDocument(select) { + const document = makeDocument({ + dmmf, + select, + rootTypeName: 'mutation', + rootField: 'createOneFloats', + }) + return String(transformDocument(document)) +} + +beforeAll(async () => { + dmmf = new DMMFClass(await getDMMF({ datamodel })) +}) + +test('serializes floats in exponential notation', () => { + const largeInt = getTransformedDocument({ + data: { + value: 100_000_000_000_000_000_000, + }, + }) + + expect(largeInt).toMatchInlineSnapshot(` + mutation { + createOneFloats(data: { + value: 1e+20 + }) { + id + value + } + } + `) + + const negativeInt = getTransformedDocument({ + data: { + value: Number.MIN_SAFE_INTEGER, + }, + }) + + expect(negativeInt).toMatchInlineSnapshot(` + mutation { + createOneFloats(data: { + value: -9.007199254740991e+15 + }) { + id + value + } + } + `) + + const otherFloat = getTransformedDocument({ + data: { + value: 13.37, + }, + }) + expect(otherFloat).toMatchInlineSnapshot(` + mutation { + createOneFloats(data: { + value: 1.337e+1 + }) { + id + value + } + } + `) +}) diff --git a/packages/client/src/__tests__/scalarListCreate.test.ts b/packages/client/src/__tests__/scalarListCreate.test.ts index 3fe24c0b8564..99fd27acaa63 100644 --- a/packages/client/src/__tests__/scalarListCreate.test.ts +++ b/packages/client/src/__tests__/scalarListCreate.test.ts @@ -54,7 +54,7 @@ describe('scalar where transformation', () => { } } someFloats: { - set: [1, 1.2] + set: [1e+0, 1.2e+0] } }) { id @@ -112,7 +112,7 @@ describe('scalar where transformation', () => { id: 5 } } - someFloats: [1, 1.2] + someFloats: [1e+0, 1.2e+0] }) { id name diff --git a/packages/client/src/runtime/query.ts b/packages/client/src/runtime/query.ts index 7094c8cd6eee..fb6049fb560d 100644 --- a/packages/client/src/runtime/query.ts +++ b/packages/client/src/runtime/query.ts @@ -651,6 +651,10 @@ function stringify(value: any, inputType?: DMMF.SchemaArgInputType) { return value } + if (typeof value === 'number' && inputType?.type === 'Float') { + return value.toExponential() + } + return JSON.stringify(value, null, 2) } diff --git a/packages/client/tests/functional/large-floats/_matrix.ts b/packages/client/tests/functional/large-floats/_matrix.ts new file mode 100644 index 000000000000..8f43b12d20b0 --- /dev/null +++ b/packages/client/tests/functional/large-floats/_matrix.ts @@ -0,0 +1,24 @@ +import { defineMatrix } from '../_utils/defineMatrix' + +export default defineMatrix(() => [ + [ + { + provider: 'sqlite', + }, + { + provider: 'postgresql', + }, + { + provider: 'mysql', + }, + { + provider: 'mongodb', + }, + { + provider: 'cockroachdb', + }, + { + provider: 'sqlserver', + }, + ], +]) diff --git a/packages/client/tests/functional/large-floats/prisma/_schema.ts b/packages/client/tests/functional/large-floats/prisma/_schema.ts new file mode 100644 index 000000000000..cf03c274492c --- /dev/null +++ b/packages/client/tests/functional/large-floats/prisma/_schema.ts @@ -0,0 +1,20 @@ +import { idForProvider } from '../../_utils/idForProvider' +import testMatrix from '../_matrix' + +export default testMatrix.setupSchema(({ provider }) => { + return /* Prisma */ ` + generator client { + provider = "prisma-client-js" + } + + datasource db { + provider = "${provider}" + url = env("DATABASE_URI_${provider}") + } + + model Floats { + id ${idForProvider(provider)} + value Float + } + ` +}) diff --git a/packages/client/tests/functional/large-floats/tests.ts b/packages/client/tests/functional/large-floats/tests.ts new file mode 100644 index 000000000000..66f1a002c7f7 --- /dev/null +++ b/packages/client/tests/functional/large-floats/tests.ts @@ -0,0 +1,32 @@ +// @ts-ignore +import type { PrismaClient } from '@prisma/client' + +import testMatrix from './_matrix' + +declare let prisma: PrismaClient + +testMatrix.setupTestSuite(() => { + test('floats', async () => { + const largeFloat = await prisma.floats.create({ + data: { value: 1e20 }, + }) + const negativeFloat = await prisma.floats.create({ + data: { value: -1e20 }, + }) + const largeInteger = await prisma.floats.create({ + data: { value: Number.MAX_SAFE_INTEGER }, + }) + const negativeInteger = await prisma.floats.create({ + data: { value: Number.MIN_SAFE_INTEGER }, + }) + const otherFloat = await prisma.floats.create({ + data: { value: 13.37 }, + }) + + expect(largeFloat.value).toEqual(1e20) + expect(negativeFloat.value).toEqual(-1e20) + expect(largeInteger.value).toEqual(Number.MAX_SAFE_INTEGER) + expect(negativeInteger.value).toEqual(Number.MIN_SAFE_INTEGER) + expect(otherFloat.value).toEqual(13.37) + }) +}) diff --git a/packages/internals/src/utils/jestSnapshotSerializer.js b/packages/internals/src/utils/jestSnapshotSerializer.js index acfa54ddbec6..f9a88bedb6e2 100644 --- a/packages/internals/src/utils/jestSnapshotSerializer.js +++ b/packages/internals/src/utils/jestSnapshotSerializer.js @@ -69,7 +69,7 @@ function normalizeBinaryFilePath(str) { } function normalizeMigrateTimestamps(str) { - return str.replace(/\d{14}/g, '20201231000000') + return str.replace(/(?