Skip to content

Commit e68fc5f

Browse files
committed
fix(relations): add test cases for relations
1 parent e4be803 commit e68fc5f

File tree

6 files changed

+126
-37
lines changed

6 files changed

+126
-37
lines changed

__tests__/fixtures/datamodels.ts

-27
This file was deleted.
+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
export const datamodelOneToOne = /* Prisma */ `
2+
model User {
3+
id Int @id @default(autoincrement())
4+
name String
5+
profile Profile?
6+
}
7+
model Profile {
8+
id Int @id @default(autoincrement())
9+
name String
10+
user User @relation(fields: [userId], references: [id])
11+
userId Int
12+
}
13+
`;
14+
15+
export const datamodelOneToOneAndManyToOne = /* Prisma */ `
16+
model User {
17+
id Int @id @default(autoincrement())
18+
name String
19+
profile Profile?
20+
posts Post[]
21+
}
22+
model Profile {
23+
id Int @id @default(autoincrement())
24+
name String
25+
user User @relation(fields: [userId], references: [id])
26+
userId Int
27+
}
28+
model Post {
29+
id Int @id @default(autoincrement())
30+
name String
31+
author User @relation(fields: [authorId], references: [id])
32+
authorId Int
33+
}
34+
`;
35+
36+
export const datamodelManyToOne = /* Prisma */ `
37+
model User {
38+
id Int @id @default(autoincrement())
39+
name String
40+
posts Post[]
41+
}
42+
model Post {
43+
id Int @id @default(autoincrement())
44+
name String
45+
author User @relation(fields: [authorId], references: [id])
46+
authorId Int
47+
}
48+
`;
49+
50+
export const datamodelManyToOneSecond = /* Prisma */ `
51+
model User {
52+
id Int @id @default(autoincrement())
53+
name String
54+
organizationPermissions OrganizationPermission[]
55+
}
56+
model Organization {
57+
id Int @id @default(autoincrement())
58+
createdAt DateTime @default(now())
59+
updatedAt DateTime @updatedAt
60+
name String
61+
62+
permissions OrganizationPermission[]
63+
}
64+
65+
model OrganizationPermission {
66+
id Int @id @default(autoincrement())
67+
createdAt DateTime @default(now())
68+
updatedAt DateTime @updatedAt
69+
70+
organization Organization @relation(fields: [organizationId], references: [id])
71+
organizationId Int
72+
73+
user User @relation(fields: [userId], references: [id])
74+
userId Int
75+
76+
accepted Boolean @default(false)
77+
@@unique([userId, organizationId])
78+
}
79+
`;

__tests__/relations.test.ts

+29-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
import { generateDMMF } from './utils/generateDMMF';
2-
import { datamodelOneToOne, datamodelManyToOne } from './fixtures/datamodels';
2+
import {
3+
datamodelOneToOne,
4+
datamodelManyToOne,
5+
datamodelManyToOneSecond,
6+
datamodelOneToOneAndManyToOne,
7+
} from './fixtures/relations.datamodel';
38
import { generateRelations } from '../src/generator/relations';
49

510
describe('Relations', () => {
@@ -12,6 +17,17 @@ describe('Relations', () => {
1217
expect(relations[0]).toMatch(expected);
1318
});
1419

20+
test('generating one-to-one and many-to-one relationship', async () => {
21+
const dmmf = await generateDMMF(datamodelOneToOneAndManyToOne);
22+
23+
const expected = 'Ref: Profile.userId - User.id';
24+
const expectedSecond = 'Ref: Post.authorId > User.id';
25+
26+
const relations = generateRelations(dmmf.datamodel.models);
27+
expect(relations[0]).toMatch(expected);
28+
expect(relations[1]).toMatch(expectedSecond);
29+
});
30+
1531
test('generating many-to-one relationship', async () => {
1632
const dmmf = await generateDMMF(datamodelManyToOne);
1733

@@ -20,4 +36,16 @@ describe('Relations', () => {
2036
const relations = generateRelations(dmmf.datamodel.models);
2137
expect(relations[0]).toMatch(expected);
2238
});
39+
40+
test('generating many-to-one relationship second', async () => {
41+
const dmmf = await generateDMMF(datamodelManyToOneSecond);
42+
43+
const expected =
44+
'Ref: OrganizationPermission.organizationId > Organization.id';
45+
const expectedSecond = 'Ref: OrganizationPermission.userId > User.id';
46+
47+
const relations = generateRelations(dmmf.datamodel.models);
48+
expect(relations[0]).toMatch(expected);
49+
expect(relations[1]).toMatch(expectedSecond);
50+
});
2351
});

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"bin": "./dist/generator.js",
66
"scripts": {
77
"build": "tsc -p .",
8+
"dev:watch": "tsc -p . --watch",
89
"dev": "tsc -p . && npm run prisma:generate",
910
"prisma:save": "npx prisma migrate save --experimental",
1011
"prisma:up": "npx prisma migrate up --experimental",

src/cli/dbml-generator.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export async function generate(options: GeneratorOptions) {
1010
try {
1111
await mkdir(options.generator.output, { recursive: true });
1212

13-
// await writeFile('./test.json', JSON.stringify(options.dmmf.datamodel));
13+
await writeFile('./test.json', JSON.stringify(options.dmmf.datamodel));
1414

1515
const dbmlSchema = generateDBMLSchema(options.dmmf);
1616

src/generator/relations.ts

+16-8
Original file line numberDiff line numberDiff line change
@@ -15,26 +15,34 @@ export function generateRelations(models: DMMF.Model[]): string[] {
1515
field.relationFromFields?.length
1616
)
1717
.forEach((field) => {
18-
const relatedTables = field.relationName!!.split('To');
18+
const relationFrom = model.name;
19+
const relationTo = field.type;
20+
21+
const relationOperator = getRelationOperator(
22+
models,
23+
relationFrom,
24+
relationTo
25+
);
26+
1927
refs.push(
20-
`Ref: ${relatedTables[0]}.${combineKeys(
28+
`Ref: ${relationFrom}.${combineKeys(
2129
field.relationFromFields!
22-
)} ${getRefOperator(models, relatedTables[1], relatedTables[0])} ${
23-
relatedTables[1]
24-
}.${combineKeys(field.relationToFields!!)}`
30+
)} ${relationOperator} ${relationTo}.${combineKeys(
31+
field.relationToFields!!
32+
)}`
2533
);
2634
});
2735
});
2836
return refs;
2937
}
3038

31-
const getRefOperator = (
39+
const getRelationOperator = (
3240
models: DMMF.Model[],
3341
from: string,
3442
to: string
3543
): string => {
36-
const model = models.find((model) => model.name === from);
37-
const field = model?.fields.find((field) => field.type === to);
44+
const model = models.find((model) => model.name === to);
45+
const field = model?.fields.find((field) => field.type === from);
3846
return field?.isList ? manyToOne : oneToOne;
3947
};
4048

0 commit comments

Comments
 (0)