diff --git a/packages/client/src/__tests__/integration/happy/prisma-promises/.gitignore b/packages/client/src/__tests__/integration/happy/prisma-promises/.gitignore deleted file mode 100644 index c8d334f884aa..000000000000 --- a/packages/client/src/__tests__/integration/happy/prisma-promises/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!dev.db diff --git a/packages/client/src/__tests__/integration/happy/prisma-promises/dev.db b/packages/client/src/__tests__/integration/happy/prisma-promises/dev.db deleted file mode 100644 index 4be62b3edd4e..000000000000 Binary files a/packages/client/src/__tests__/integration/happy/prisma-promises/dev.db and /dev/null differ diff --git a/packages/client/src/__tests__/integration/happy/prisma-promises/schema.prisma b/packages/client/src/__tests__/integration/happy/prisma-promises/schema.prisma deleted file mode 100644 index f82593508957..000000000000 --- a/packages/client/src/__tests__/integration/happy/prisma-promises/schema.prisma +++ /dev/null @@ -1,29 +0,0 @@ -datasource db { - provider = "sqlite" - url = "file:dev.db" -} - -generator client { - provider = "prisma-client-js" -} - -// / User model comment -model User { - id String @default(uuid()) @id - email String @unique - age Int - // / name comment - name String? - posts Post[] -} - -model Post { - id String @default(cuid()) @id - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - published Boolean - title String - content String? - authorId String? - author User? @relation(fields: [authorId], references: [id]) -} diff --git a/packages/client/src/__tests__/integration/happy/prisma-promises/test.ts b/packages/client/src/__tests__/integration/happy/prisma-promises/test.ts deleted file mode 100644 index ca200f8bc4d8..000000000000 --- a/packages/client/src/__tests__/integration/happy/prisma-promises/test.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { getTestClient } from '../../../../utils/getTestClient' - -describe('prisma promises', () => { - /** - * Requests must get sent if we call `.catch` - */ - test('catch', async () => { - const PrismaClient = await getTestClient() - const prisma = new PrismaClient() - const handler = (e) => Promise.reject(e) - - const remove = await prisma.user.deleteMany().catch(handler) - const queryRaw = await prisma.$queryRawUnsafe('SELECT 1').catch(handler) - const executeRaw = await prisma.$executeRawUnsafe('DELETE FROM User').catch(handler) - const findMany = await prisma.user.findMany().catch(handler) - - expect(remove).toMatchInlineSnapshot(` - Object { - count: 0, - } - `) - expect(queryRaw).toMatchInlineSnapshot(` - Array [ - Object { - 1: 1n, - }, - ] - `) - expect(executeRaw).toMatchInlineSnapshot(`0`) - expect(findMany).toMatchInlineSnapshot(`Array []`) - - await prisma.$disconnect() - }) - - /** - * Requests must get sent if we call `.finally` - */ - test('finally', async () => { - const PrismaClient = await getTestClient() - const prisma = new PrismaClient() - const handler = () => {} - - const remove = await prisma.user.deleteMany().finally(handler) - const queryRaw = await prisma.$queryRawUnsafe('SELECT 1').finally(handler) - const executeRaw = await prisma.$executeRawUnsafe('DELETE FROM User').finally(handler) - const findMany = await prisma.user.findMany().finally(handler) - - expect(remove).toMatchInlineSnapshot(` - Object { - count: 0, - } - `) - expect(queryRaw).toMatchInlineSnapshot(` - Array [ - Object { - 1: 1n, - }, - ] - `) - expect(executeRaw).toMatchInlineSnapshot(`0`) - expect(findMany).toMatchInlineSnapshot(`Array []`) - - await prisma.$disconnect() - }) -}) diff --git a/packages/client/src/__tests__/integration/happy/prismaPromise/.gitignore b/packages/client/src/__tests__/integration/happy/prismaPromise/.gitignore deleted file mode 100644 index 97952752a72b..000000000000 --- a/packages/client/src/__tests__/integration/happy/prismaPromise/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!dev.db \ No newline at end of file diff --git a/packages/client/src/__tests__/integration/happy/prismaPromise/dev.db b/packages/client/src/__tests__/integration/happy/prismaPromise/dev.db deleted file mode 100644 index 09b6082e5a81..000000000000 Binary files a/packages/client/src/__tests__/integration/happy/prismaPromise/dev.db and /dev/null differ diff --git a/packages/client/src/__tests__/integration/happy/prismaPromise/schema.prisma b/packages/client/src/__tests__/integration/happy/prismaPromise/schema.prisma deleted file mode 100644 index db2da9f50439..000000000000 --- a/packages/client/src/__tests__/integration/happy/prismaPromise/schema.prisma +++ /dev/null @@ -1,66 +0,0 @@ -datasource db { - provider = "sqlite" - url = "file:dev.db" -} - -generator client { - provider = "prisma-client-js" - binaryTargets = ["native"] -} - -model User { - id String @id @default(cuid()) - email String @unique - name String? - age Int? - posts Post[] - likes Like[] - property Property? @relation(fields: [propertyId], references: [id]) - propertyId String? - Banking Banking? -} - -model Property { - id String @id @default(cuid()) - house House @relation(fields: [houseId], references: [id]) - users User[] - houseId String -} - -model House { - id String @id @default(cuid()) - like Like @relation(fields: [likeId], references: [id]) - properties Property[] - likeId String -} - -model Post { - id String @id @default(cuid()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - published Boolean - title String - content String? - authorId String? - author User? @relation(fields: [authorId], references: [id]) - Like Like[] -} - -model Like { - id String @id @default(cuid()) - userId String - user User @relation(fields: [userId], references: [id]) - postId String - post Post @relation(fields: [postId], references: [id]) - - House House[] - @@unique([userId, postId]) -} - -model Banking { - id String @id @default(cuid()) - userId String @unique - user User? @relation(fields: [userId], references: [id]) - iban String - bic String -} \ No newline at end of file diff --git a/packages/client/src/__tests__/integration/happy/prismaPromise/test.ts b/packages/client/src/__tests__/integration/happy/prismaPromise/test.ts deleted file mode 100644 index 1e3805afe672..000000000000 --- a/packages/client/src/__tests__/integration/happy/prismaPromise/test.ts +++ /dev/null @@ -1,101 +0,0 @@ -import { getTestClient } from '../../../../utils/getTestClient' - -let prisma -describe('prismaPromise', () => { - test('repeated calls to .then', async () => { - const createPromise = prisma.user.create({ - data: { - email: 'email@email.em', - }, - }) - - // repeated calls to then should not change the result - const createResult1 = await createPromise.then() - const createResult2 = await createPromise.then() - - expect(createResult1).toStrictEqual(createResult2) - }) - - test('repeated calls to .catch', async () => { - const createPromise = prisma.user.create({ - data: { - email: 'email@email.em', - }, - }) - - // repeated calls to catch should not change the result - const createResult1 = await createPromise.catch() - const createResult2 = await createPromise.catch() - - expect(createResult1).toStrictEqual(createResult2) - }) - - test('repeated calls to .finally', async () => { - const createPromise = prisma.user.create({ - data: { - email: 'email@email.em', - }, - }) - - // repeated calls to finally should not change the result - const createResult1 = await createPromise.finally() - const createResult2 = await createPromise.finally() - - expect(createResult1).toStrictEqual(createResult2) - }) - - test('repeated mixed calls to .then, .catch, .finally', async () => { - const createPromise = prisma.user.create({ - data: { - email: 'email@email.em', - }, - }) - - // repeated calls to then & co should not change the result - const createResult1 = await createPromise.finally().then().catch() - const createResult2 = await createPromise.catch().finally().then() - - expect(createResult1).toStrictEqual(createResult2) - }) - - test('repeated calls to .requestTransaction', async () => { - const createPromise = prisma.user.create({ - data: { - email: 'email@email.em', - }, - }) - - // repeated calls to then & co should not change the result - const createResult1 = await createPromise.requestTransaction(1) - const createResult2 = await createPromise.requestTransaction(1) - - expect(createResult1).toStrictEqual(createResult2) - }) - - test('fluent promises should have promise properties', async () => { - const findUniquePromise = prisma.user.findUnique({ - where: { - email: 'email@email.em', - }, - }) - - expect('then' in findUniquePromise).toBe(true) - expect('finally' in findUniquePromise).toBe(true) - expect('catch' in findUniquePromise).toBe(true) - - await findUniquePromise.finally() - }) - - beforeAll(async () => { - const PrismaClient = await getTestClient() - prisma = new PrismaClient() - }) - - beforeEach(async () => { - await prisma.user.deleteMany() - }) - - afterAll(async () => { - await prisma.$disconnect() - }) -}) diff --git a/packages/client/tests/functional/prisma-promise/_matrix.ts b/packages/client/tests/functional/prisma-promise/_matrix.ts new file mode 100644 index 000000000000..655d4c217edc --- /dev/null +++ b/packages/client/tests/functional/prisma-promise/_matrix.ts @@ -0,0 +1,24 @@ +import { defineMatrix } from '../_utils/defineMatrix' + +export default defineMatrix(() => [ + [ + { + provider: 'sqlite', + }, + { + provider: 'postgresql', + }, + { + provider: 'mysql', + }, + { + provider: 'sqlserver', + }, + { + provider: 'cockroachdb', + }, + { + provider: 'mongodb', + }, + ], +]) diff --git a/packages/client/tests/functional/prisma-promise/prisma/_schema.ts b/packages/client/tests/functional/prisma-promise/prisma/_schema.ts new file mode 100644 index 000000000000..53038f9ab0d3 --- /dev/null +++ b/packages/client/tests/functional/prisma-promise/prisma/_schema.ts @@ -0,0 +1,21 @@ +import { idForProvider } from '../../_utils/idForProvider' +import testMatrix from '../_matrix' + +export default testMatrix.setupSchema(({ provider }) => { + return /* Prisma */ ` + datasource db { + provider = "${provider}" + url = env("DATABASE_URI_${provider}") + } + + generator client { + provider = "prisma-client-js" + binaryTargets = ["native"] + } + + model User { + id ${idForProvider(provider)} + email String @unique + } + ` +}) diff --git a/packages/client/tests/functional/prisma-promise/tests.ts b/packages/client/tests/functional/prisma-promise/tests.ts new file mode 100644 index 000000000000..d85f31629c33 --- /dev/null +++ b/packages/client/tests/functional/prisma-promise/tests.ts @@ -0,0 +1,293 @@ +import { faker } from '@faker-js/faker' + +import testMatrix from './_matrix' + +// @ts-ignore this is just for type checks +declare let prisma: import('@prisma/client').PrismaClient + +testMatrix.setupTestSuite(({ provider }) => { + const tests = [ + [ + 'create', + (email: string) => { + return prisma.user.create({ + data: { + email, + }, + }) + }, + ], + ...(provider !== 'sqlite' + ? [ + [ + 'createMany', + (email: string) => { + // @ts-test-if: provider !== 'sqlite' + return prisma.user.createMany({ + data: [ + { + email, + }, + ], + }) + }, + ], + ] + : []), + [ + 'findMany', + (email: string) => { + return prisma.user.findMany({ + where: { + email, + }, + }) + }, + ], + [ + 'findFirst', + (email: string) => { + return prisma.user.findFirst({ + where: { + email, + }, + }) + }, + ], + [ + 'findUnique', + (email: string) => { + return prisma.user.findUnique({ + where: { + email, + }, + }) + }, + ], + [ + 'findUniqueOrThrow', + (email: string) => { + return prisma.user.findUniqueOrThrow({ + where: { + email, + }, + }) + }, + ], + [ + 'findFirstOrThrow', + (email: string) => { + return prisma.user.findFirstOrThrow({ + where: { + email, + }, + }) + }, + ], + [ + 'update', + (email: string) => { + return prisma.user.update({ + where: { + email, + }, + data: { + email, + }, + }) + }, + ], + [ + 'updateMany', + (email: string) => { + return prisma.user.updateMany({ + where: { + email, + }, + data: { + email, + }, + }) + }, + ], + [ + 'delete', + (email: string) => { + return prisma.user.delete({ + where: { + email, + }, + }) + }, + ], + [ + 'deleteMany', + (email: string) => { + return prisma.user.deleteMany({ + where: { + email, + }, + }) + }, + ], + [ + 'aggregate', + (email: string) => { + return prisma.user.aggregate({ + where: { + email, + }, + _count: true, + }) + }, + ], + [ + 'count', + (email: string) => { + return prisma.user.count({ + where: { + email, + }, + }) + }, + ], + ...(provider !== 'mongodb' + ? [ + [ + '$queryRaw', + () => { + // @ts-test-if: provider !== 'mongodb' + return prisma.$queryRaw`SELECT 1 + 1;` + }, + ], + [ + '$queryRawUnsafe', + () => { + // @ts-test-if: provider !== 'mongodb' + return prisma.$queryRawUnsafe(`SELECT 1 + 1;`) + }, + ], + ...(provider !== 'sqlite' + ? [ + [ + '$executeRaw', + () => { + // @ts-test-if: provider !== 'mongodb' + return prisma.$executeRaw`SELECT 1 + 1;` + }, + ], + [ + '$executeRawUnsafe', + () => { + // @ts-test-if: provider !== 'mongodb' + return prisma.$executeRawUnsafe(`SELECT 1 + 1;`) + }, + ], + ] + : []), + ] + : []), + ...(provider === 'mongodb' + ? [ + [ + '$runCommandRaw', + () => { + // @ts-test-if: provider === 'mongodb' + return prisma.$runCommandRaw({ + aggregate: 'User', + pipeline: [{ $match: { name: 'A' } }, { $project: { email: true, _id: false } }], + explain: false, + }) + }, + ], + ] + : []), + ] + + // @ts-ignore function defined in matrix + describe.each(tests)('%s', (name, fn) => { + const email = faker.internet.email() + const createPromise = () => { + // @ts-ignore function defined in matrix + return (fn as (email: string) => any)(email) + } + + beforeEach(async () => { + if ( + ['delete', 'deleteMany', 'update', 'updateMany', 'findFirstOrThrow', 'findUniqueOrThrow'].includes( + name as string, + ) + ) { + await prisma.user.create({ data: { email } }) + } + }) + + afterEach(async () => { + try { + await prisma.user.delete({ where: { email } }) + } catch (error) { + // ignore + } + }) + + test('repeated calls to .then', async () => { + const promise = createPromise() + + // repeated calls to then should not change the result + const res1 = await promise.then() + const res2 = await promise.then() + + expect(res1).toStrictEqual(res2) + }) + + test('repeated calls to .catch', async () => { + const promise = createPromise() + + // repeated calls to catch should not change the result + const res1 = await promise.catch() + const res2 = await promise.catch() + + expect(res1).toStrictEqual(res2) + }) + + test('repeated calls to .finally', async () => { + const promise = createPromise() + + // repeated calls to finally should not change the result + const res1 = await promise.finally() + const res2 = await promise.finally() + + expect(res1).toStrictEqual(res2) + }) + + test('repeated mixed calls to .then, .catch, .finally', async () => { + const promise = createPromise() + + // repeated calls to then & co should not change the result + const res1 = await promise.finally().then().catch() + const res2 = await promise.catch().finally().then() + + expect(res1).toStrictEqual(res2) + }) + + test('repeated calls to .requestTransaction', async () => { + const promise = createPromise() + + // repeated calls to then & co should not change the result + const res1 = await promise.requestTransaction(1) + const res2 = await promise.requestTransaction(1) + + expect(res1).toStrictEqual(res2) + }) + + test('fluent promises should have promise properties', async () => { + const promise = createPromise() + + expect('then' in promise).toBe(true) + expect('finally' in promise).toBe(true) + expect('catch' in promise).toBe(true) + + await promise.finally() + }) + }) +})