Skip to content

Commit 96eced7

Browse files
Add ORM example smoke tests (#8404)
* Describe added tests * Fix npm audit vulnerabilities * Fix CI runner issue
1 parent f8e9a7d commit 96eced7

File tree

11 files changed

+172
-65
lines changed

11 files changed

+172
-65
lines changed

generator-prisma-client/basic-typedsql/prisma.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@ export default defineConfig({
99
seed: 'tsx ./prisma/seed.ts',
1010
},
1111
datasource: {
12-
url: "file:./dev.db",
12+
url: "file:./prisma/dev.db",
1313
},
1414
})

generator-prisma-client/basic-typedsql/prisma/seed.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ enum EventType {
1717
CheckedOut = 'CheckedOut',
1818
}
1919

20-
const adapter = new PrismaBetterSqlite3({ url: 'file:./prisma/dev.db' })
20+
const adapter = new PrismaBetterSqlite3({
21+
url: process.env.DATABASE_URL || 'file:./prisma/dev.db',
22+
})
2123
const prisma = new PrismaClient({ adapter })
2224

2325
async function main() {

generator-prisma-client/nextjs-starter-webpack-with-middleware/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ To successfully run the project, you will need a **Prisma Postgres** connection
2929
generator edge {
3030
provider = "prisma-client"
3131
output = "../lib/generated/prisma-edge"
32-
runtime = "vercel"
32+
runtime = "vercel-edge"
3333
}
3434
```
3535

generator-prisma-client/nextjs-starter-webpack-with-middleware/prisma/schema.prisma

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ generator client {
1010
generator edge {
1111
provider = "prisma-client"
1212
output = "../lib/generated/prisma-edge"
13-
runtime = "vercel"
13+
runtime = "vercel-edge"
1414
}
1515

1616
datasource db {
Lines changed: 43 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,46 @@
11
/* eslint-disable */
2-
import type { Prisma, User, Post } from '../prisma/generated/client'
3-
import type { PothosPrismaDatamodel } from '@pothos/plugin-prisma'
2+
import type { Prisma, User, Post } from "../prisma/generated/client/client.js";
3+
import type { PothosPrismaDatamodel } from "@pothos/plugin-prisma";
44
export default interface PrismaTypes {
5-
User: {
6-
Name: 'User'
7-
Shape: User
8-
Include: Prisma.UserInclude
9-
Select: Prisma.UserSelect
10-
OrderBy: Prisma.UserOrderByWithRelationInput
11-
WhereUnique: Prisma.UserWhereUniqueInput
12-
Where: Prisma.UserWhereInput
13-
Create: {}
14-
Update: {}
15-
RelationName: 'posts'
16-
ListRelations: 'posts'
17-
Relations: {
18-
posts: {
19-
Shape: Post[]
20-
Name: 'Post'
21-
Nullable: false
22-
}
23-
}
24-
}
25-
Post: {
26-
Name: 'Post'
27-
Shape: Post
28-
Include: Prisma.PostInclude
29-
Select: Prisma.PostSelect
30-
OrderBy: Prisma.PostOrderByWithRelationInput
31-
WhereUnique: Prisma.PostWhereUniqueInput
32-
Where: Prisma.PostWhereInput
33-
Create: {}
34-
Update: {}
35-
RelationName: 'author'
36-
ListRelations: never
37-
Relations: {
38-
author: {
39-
Shape: User | null
40-
Name: 'User'
41-
Nullable: true
42-
}
43-
}
44-
}
45-
}
46-
export function getDatamodel(): PothosPrismaDatamodel {
47-
return JSON.parse(
48-
'{"datamodel":{"models":{"User":{"fields":[{"type":"Int","kind":"scalar","name":"id","isRequired":true,"isList":false,"hasDefaultValue":true,"isUnique":false,"isId":true,"isUpdatedAt":false},{"type":"String","kind":"scalar","name":"email","isRequired":true,"isList":false,"hasDefaultValue":false,"isUnique":true,"isId":false,"isUpdatedAt":false},{"type":"String","kind":"scalar","name":"name","isRequired":false,"isList":false,"hasDefaultValue":false,"isUnique":false,"isId":false,"isUpdatedAt":false},{"type":"Post","kind":"object","name":"posts","isRequired":true,"isList":true,"hasDefaultValue":false,"isUnique":false,"isId":false,"relationName":"PostToUser","relationFromFields":[],"isUpdatedAt":false}],"primaryKey":null,"uniqueIndexes":[]},"Post":{"fields":[{"type":"Int","kind":"scalar","name":"id","isRequired":true,"isList":false,"hasDefaultValue":true,"isUnique":false,"isId":true,"isUpdatedAt":false},{"type":"DateTime","kind":"scalar","name":"createdAt","isRequired":true,"isList":false,"hasDefaultValue":true,"isUnique":false,"isId":false,"isUpdatedAt":false},{"type":"DateTime","kind":"scalar","name":"updatedAt","isRequired":true,"isList":false,"hasDefaultValue":false,"isUnique":false,"isId":false,"isUpdatedAt":true},{"type":"String","kind":"scalar","name":"title","isRequired":true,"isList":false,"hasDefaultValue":false,"isUnique":false,"isId":false,"isUpdatedAt":false},{"type":"String","kind":"scalar","name":"content","isRequired":false,"isList":false,"hasDefaultValue":false,"isUnique":false,"isId":false,"isUpdatedAt":false},{"type":"Boolean","kind":"scalar","name":"published","isRequired":true,"isList":false,"hasDefaultValue":true,"isUnique":false,"isId":false,"isUpdatedAt":false},{"type":"Int","kind":"scalar","name":"viewCount","isRequired":true,"isList":false,"hasDefaultValue":true,"isUnique":false,"isId":false,"isUpdatedAt":false},{"type":"User","kind":"object","name":"author","isRequired":false,"isList":false,"hasDefaultValue":false,"isUnique":false,"isId":false,"relationName":"PostToUser","relationFromFields":["authorId"],"isUpdatedAt":false},{"type":"Int","kind":"scalar","name":"authorId","isRequired":false,"isList":false,"hasDefaultValue":false,"isUnique":false,"isId":false,"isUpdatedAt":false}],"primaryKey":null,"uniqueIndexes":[]}}}}',
49-
)
5+
User: {
6+
Name: "User";
7+
Shape: User;
8+
Include: Prisma.UserInclude;
9+
Select: Prisma.UserSelect;
10+
OrderBy: Prisma.UserOrderByWithRelationInput;
11+
WhereUnique: Prisma.UserWhereUniqueInput;
12+
Where: Prisma.UserWhereInput;
13+
Create: {};
14+
Update: {};
15+
RelationName: "posts";
16+
ListRelations: "posts";
17+
Relations: {
18+
posts: {
19+
Shape: Post[];
20+
Name: "Post";
21+
Nullable: false;
22+
};
23+
};
24+
};
25+
Post: {
26+
Name: "Post";
27+
Shape: Post;
28+
Include: Prisma.PostInclude;
29+
Select: Prisma.PostSelect;
30+
OrderBy: Prisma.PostOrderByWithRelationInput;
31+
WhereUnique: Prisma.PostWhereUniqueInput;
32+
Where: Prisma.PostWhereInput;
33+
Create: {};
34+
Update: {};
35+
RelationName: "author";
36+
ListRelations: never;
37+
Relations: {
38+
author: {
39+
Shape: User | null;
40+
Name: "User";
41+
Nullable: true;
42+
};
43+
};
44+
};
5045
}
46+
export function getDatamodel(): PothosPrismaDatamodel { return JSON.parse("{\"datamodel\":{\"models\":{\"User\":{\"fields\":[{\"type\":\"Int\",\"kind\":\"scalar\",\"name\":\"id\",\"isRequired\":true,\"isList\":false,\"hasDefaultValue\":true,\"isUnique\":false,\"isId\":true,\"isUpdatedAt\":false},{\"type\":\"String\",\"kind\":\"scalar\",\"name\":\"email\",\"isRequired\":true,\"isList\":false,\"hasDefaultValue\":false,\"isUnique\":true,\"isId\":false,\"isUpdatedAt\":false},{\"type\":\"String\",\"kind\":\"scalar\",\"name\":\"name\",\"isRequired\":false,\"isList\":false,\"hasDefaultValue\":false,\"isUnique\":false,\"isId\":false,\"isUpdatedAt\":false},{\"type\":\"Post\",\"kind\":\"object\",\"name\":\"posts\",\"isRequired\":true,\"isList\":true,\"hasDefaultValue\":false,\"isUnique\":false,\"isId\":false,\"relationName\":\"PostToUser\",\"relationFromFields\":[],\"isUpdatedAt\":false}],\"primaryKey\":null,\"uniqueIndexes\":[]},\"Post\":{\"fields\":[{\"type\":\"Int\",\"kind\":\"scalar\",\"name\":\"id\",\"isRequired\":true,\"isList\":false,\"hasDefaultValue\":true,\"isUnique\":false,\"isId\":true,\"isUpdatedAt\":false},{\"type\":\"DateTime\",\"kind\":\"scalar\",\"name\":\"createdAt\",\"isRequired\":true,\"isList\":false,\"hasDefaultValue\":true,\"isUnique\":false,\"isId\":false,\"isUpdatedAt\":false},{\"type\":\"DateTime\",\"kind\":\"scalar\",\"name\":\"updatedAt\",\"isRequired\":true,\"isList\":false,\"hasDefaultValue\":false,\"isUnique\":false,\"isId\":false,\"isUpdatedAt\":true},{\"type\":\"String\",\"kind\":\"scalar\",\"name\":\"title\",\"isRequired\":true,\"isList\":false,\"hasDefaultValue\":false,\"isUnique\":false,\"isId\":false,\"isUpdatedAt\":false},{\"type\":\"String\",\"kind\":\"scalar\",\"name\":\"content\",\"isRequired\":false,\"isList\":false,\"hasDefaultValue\":false,\"isUnique\":false,\"isId\":false,\"isUpdatedAt\":false},{\"type\":\"Boolean\",\"kind\":\"scalar\",\"name\":\"published\",\"isRequired\":true,\"isList\":false,\"hasDefaultValue\":true,\"isUnique\":false,\"isId\":false,\"isUpdatedAt\":false},{\"type\":\"Int\",\"kind\":\"scalar\",\"name\":\"viewCount\",\"isRequired\":true,\"isList\":false,\"hasDefaultValue\":true,\"isUnique\":false,\"isId\":false,\"isUpdatedAt\":false},{\"type\":\"User\",\"kind\":\"object\",\"name\":\"author\",\"isRequired\":false,\"isList\":false,\"hasDefaultValue\":false,\"isUnique\":false,\"isId\":false,\"relationName\":\"PostToUser\",\"relationFromFields\":[\"authorId\"],\"isUpdatedAt\":false},{\"type\":\"Int\",\"kind\":\"scalar\",\"name\":\"authorId\",\"isRequired\":false,\"isList\":false,\"hasDefaultValue\":false,\"isUnique\":false,\"isId\":false,\"isUpdatedAt\":false}],\"primaryKey\":null,\"uniqueIndexes\":[]}}}}"); }

orm/solid-start/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
"start": "vinxi start"
88
},
99
"dependencies": {
10-
"@prisma/client": "^7.0.0",
11-
"@prisma/adapter-pg": "^7.0.0",
10+
"@prisma/client": "7.3.0",
11+
"@prisma/adapter-pg": "7.3.0",
1212
"@solidjs/start": "1.1.7",
1313
"solid-js": "1.9.10",
1414
"vinxi": "0.5.8",
@@ -21,7 +21,7 @@
2121
"@tailwindcss/postcss": "4.1.13",
2222
"dotenv": "^17.2.1",
2323
"postcss": "8.5.6",
24-
"prisma": "7.0.0",
24+
"prisma": "7.3.0",
2525
"tailwindcss": "4.1.11",
2626
"tsx": "4.20.6",
2727
"@types/pg": "^8.15.6"

tests/databases.test.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,24 @@
1-
import { testExample } from './fixtures.js'
1+
import { testExample, testSqliteExample } from './fixtures.js'
22
import { describe, test } from 'vitest'
33

44
describe.concurrent('Database Examples', () => {
55
// PostgreSQL examples
66
testExample('databases/prisma-postgres')
7+
testSqliteExample('databases/turso')
78

89
// Skipped examples
910
describe('databases/postgresql-supabase', () => {
1011
test.skip('requires Supabase setup', () => {})
1112
})
1213

14+
describe('databases/cockroachdb', () => {
15+
test.skip('requires CockroachDB setup', () => {})
16+
})
17+
18+
describe('databases/mongodb', () => {
19+
test.skip('requires MongoDB setup', () => {})
20+
})
21+
1322
describe('databases/sql-server', () => {
1423
test.skip('requires SQL Server setup', () => {})
1524
})

tests/deployment-platforms.test.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { describe, test } from 'vitest'
2+
3+
describe.concurrent('Deployment Platform Examples', () => {
4+
describe('deployment-platforms/aws-lambda', () => {
5+
test.skip('requires AWS Lambda setup', () => {})
6+
})
7+
8+
describe('deployment-platforms/azure-functions', () => {
9+
test.skip('requires Azure Functions + SQL Server setup', () => {})
10+
})
11+
12+
describe('deployment-platforms/edge', () => {
13+
test.skip('requires edge runtime setup (Cloudflare/D1)', () => {})
14+
})
15+
16+
describe('deployment-platforms/google-cloud-functions', () => {
17+
test.skip('requires Google Cloud Functions setup', () => {})
18+
})
19+
20+
describe('deployment-platforms/heroku', () => {
21+
test.skip('requires Heroku setup', () => {})
22+
})
23+
24+
describe('deployment-platforms/railway', () => {
25+
test.skip('requires Railway setup', () => {})
26+
})
27+
28+
describe('deployment-platforms/render', () => {
29+
test.skip('requires Render setup', () => {})
30+
})
31+
32+
describe('deployment-platforms/vercel', () => {
33+
test.skip('requires Vercel setup', () => {})
34+
})
35+
})

tests/fixtures.ts

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,11 @@ export function testExample(examplePath: string, options?: TestExampleOptions) {
2222
test('prisma setup', async () => {
2323
server = await startPrismaDevServer({ databaseIdleTimeoutMillis: 300000 })
2424
const url = server.database.connectionString
25+
const databaseUrl = url.startsWith('postgres://')
26+
? url.replace('postgres://', 'postgresql://')
27+
: url
2528
const cwd = path.join(process.cwd(), examplePath)
26-
const env = { ...process.env, DATABASE_URL: url }
29+
const env = { ...process.env, DATABASE_URL: databaseUrl, DIRECT_URL: databaseUrl }
2730

2831
console.log(`\n[${examplePath}] Installing dependencies...`)
2932
await execa('npm', ['install'], { cwd, env, stdio: 'inherit' })
@@ -56,32 +59,39 @@ export function testExample(examplePath: string, options?: TestExampleOptions) {
5659
}
5760

5861
// For SQLite examples that don't need @prisma/dev server
59-
export function testSqliteExample(examplePath: string, options?: { generateSql?: boolean }) {
62+
export function testSqliteExample(
63+
examplePath: string,
64+
options?: { generateSql?: boolean; env?: NodeJS.ProcessEnv }
65+
) {
6066
describe(examplePath, () => {
6167
test('prisma setup', async () => {
6268
const cwd = path.join(process.cwd(), examplePath)
69+
const env = { ...process.env, ...options?.env }
6370

64-
// Remove existing SQLite database to ensure clean state
65-
const dbPath = path.join(cwd, 'dev.db')
66-
if (fs.existsSync(dbPath)) {
67-
fs.unlinkSync(dbPath)
71+
// Remove existing SQLite databases to ensure clean state
72+
const dbPaths = [path.join(cwd, 'dev.db'), path.join(cwd, 'prisma', 'dev.db')]
73+
for (const dbPath of dbPaths) {
74+
if (fs.existsSync(dbPath)) {
75+
fs.unlinkSync(dbPath)
76+
}
6877
}
6978

7079
console.log(`\n[${examplePath}] Installing dependencies...`)
71-
await execa('npm', ['install'], { cwd, stdio: 'inherit' })
80+
await execa('npm', ['install'], { cwd, env, stdio: 'inherit' })
7281

7382
console.log(`\n[${examplePath}] Running prisma generate...`)
74-
await execa('npx', ['prisma', 'generate'], { cwd, stdio: 'inherit' })
83+
await execa('npx', ['prisma', 'generate'], { cwd, env, stdio: 'inherit' })
7584

7685
console.log(`\n[${examplePath}] Running prisma db push...`)
7786
await execa('npx', ['prisma', 'db', 'push', '--accept-data-loss'], {
7887
cwd,
88+
env,
7989
stdio: 'inherit',
8090
})
8191

8292
if (options?.generateSql) {
8393
console.log(`\n[${examplePath}] Running prisma generate --sql...`)
84-
await execa('npx', ['prisma', 'generate', '--sql'], { cwd, stdio: 'inherit' })
94+
await execa('npx', ['prisma', 'generate', '--sql'], { cwd, env, stdio: 'inherit' })
8595
}
8696

8797
// Check for seed in prisma.config.ts (Prisma v7+)
@@ -90,7 +100,7 @@ export function testSqliteExample(examplePath: string, options?: { generateSql?:
90100
const content = fs.readFileSync(configPath, 'utf-8')
91101
if (content.includes('seed:')) {
92102
console.log(`\n[${examplePath}] Running prisma db seed...`)
93-
await execa('npx', ['prisma', 'db', 'seed'], { cwd, stdio: 'inherit' })
103+
await execa('npx', ['prisma', 'db', 'seed'], { cwd, env, stdio: 'inherit' })
94104
}
95105
}
96106

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { describe, test } from 'vitest'
2+
import { testExample, testSqliteExample } from './fixtures.js'
3+
4+
describe.concurrent('Generator Prisma Client Examples', () => {
5+
testExample('generator-prisma-client/esbuild-cjs')
6+
testExample('generator-prisma-client/nextjs-starter-turbopack')
7+
testExample('generator-prisma-client/nextjs-starter-webpack')
8+
testExample('generator-prisma-client/nextjs-starter-webpack-with-middleware')
9+
testExample('generator-prisma-client/nuxt3-starter-nodejs')
10+
testExample('generator-prisma-client/nuxt4-starter-nodejs')
11+
testExample('generator-prisma-client/react-router-starter-nodejs')
12+
13+
testSqliteExample('generator-prisma-client/basic-typedsql', { generateSql: true })
14+
testSqliteExample('generator-prisma-client/vitest-esm-nodejs')
15+
16+
describe('generator-prisma-client/aws-lambda-sst-esbuild', () => {
17+
test.skip('requires SST/AWS runtime setup', () => {})
18+
})
19+
20+
describe('generator-prisma-client/bun', () => {
21+
test.skip('requires Bun runtime', () => {})
22+
})
23+
24+
describe('generator-prisma-client/deno-deploy', () => {
25+
test.skip('requires Deno runtime', () => {})
26+
})
27+
28+
describe('generator-prisma-client/react-router-starter-cloudflare-workerd', () => {
29+
test.skip('requires Cloudflare workerd runtime', () => {})
30+
})
31+
32+
describe('generator-prisma-client/nextjs-starter-webpack-monorepo', () => {
33+
test.skip('requires pnpm workspace/monorepo tooling', () => {})
34+
})
35+
36+
describe('generator-prisma-client/nextjs-starter-webpack-turborepo', () => {
37+
test.skip('requires pnpm/turborepo tooling', () => {})
38+
})
39+
})

0 commit comments

Comments
 (0)