mirror of
https://github.com/johndoe6345789/metabuilder.git
synced 2026-04-25 14:25:02 +00:00
202 lines
6.0 KiB
TypeScript
202 lines
6.0 KiB
TypeScript
import { describe, it, expect } from 'vitest'
|
|
import {
|
|
computeSchemaChecksum,
|
|
entityToPrisma,
|
|
fieldToPrisma,
|
|
type PackageSchemaEntity,
|
|
type PackageSchemaField,
|
|
} from './schema-registry'
|
|
|
|
describe('schema-registry', () => {
|
|
describe('computeSchemaChecksum', () => {
|
|
it.each([
|
|
{
|
|
name: 'simple entity',
|
|
entity: {
|
|
name: 'TestEntity',
|
|
version: '1.0',
|
|
fields: {
|
|
id: { type: 'cuid', primary: true },
|
|
name: { type: 'string', required: true },
|
|
},
|
|
},
|
|
expectLength: 16,
|
|
},
|
|
{
|
|
name: 'entity with indexes',
|
|
entity: {
|
|
name: 'IndexedEntity',
|
|
version: '1.0',
|
|
fields: {
|
|
id: { type: 'cuid', primary: true },
|
|
tenantId: { type: 'string', index: true },
|
|
},
|
|
indexes: [{ fields: ['tenantId'] }],
|
|
},
|
|
expectLength: 16,
|
|
},
|
|
])('computes $name checksum', ({ entity, expectLength }) => {
|
|
const checksum = computeSchemaChecksum(entity as PackageSchemaEntity)
|
|
expect(checksum).toHaveLength(expectLength)
|
|
expect(typeof checksum).toBe('string')
|
|
})
|
|
|
|
it('returns same checksum for identical entities', () => {
|
|
const entity: PackageSchemaEntity = {
|
|
name: 'Test',
|
|
version: '1.0',
|
|
fields: { id: { type: 'cuid', primary: true } },
|
|
}
|
|
const checksum1 = computeSchemaChecksum(entity)
|
|
const checksum2 = computeSchemaChecksum(entity)
|
|
expect(checksum1).toBe(checksum2)
|
|
})
|
|
|
|
it('returns different checksum for different entities', () => {
|
|
const entity1: PackageSchemaEntity = {
|
|
name: 'Test1',
|
|
version: '1.0',
|
|
fields: { id: { type: 'cuid', primary: true } },
|
|
}
|
|
const entity2: PackageSchemaEntity = {
|
|
name: 'Test2',
|
|
version: '1.0',
|
|
fields: { id: { type: 'cuid', primary: true } },
|
|
}
|
|
const checksum1 = computeSchemaChecksum(entity1)
|
|
const checksum2 = computeSchemaChecksum(entity2)
|
|
expect(checksum1).not.toBe(checksum2)
|
|
})
|
|
|
|
it('ignores description changes', () => {
|
|
const entity1: PackageSchemaEntity = {
|
|
name: 'Test',
|
|
version: '1.0',
|
|
description: 'Description 1',
|
|
fields: { id: { type: 'cuid', primary: true } },
|
|
}
|
|
const entity2: PackageSchemaEntity = {
|
|
name: 'Test',
|
|
version: '1.0',
|
|
description: 'Description 2',
|
|
fields: { id: { type: 'cuid', primary: true } },
|
|
}
|
|
expect(computeSchemaChecksum(entity1)).toBe(computeSchemaChecksum(entity2))
|
|
})
|
|
})
|
|
|
|
describe('fieldToPrisma', () => {
|
|
it.each([
|
|
{
|
|
name: 'id',
|
|
field: { type: 'cuid', primary: true, generated: true },
|
|
expected: ' id String @id @default(cuid())',
|
|
},
|
|
{
|
|
name: 'name',
|
|
field: { type: 'string', required: true },
|
|
expected: ' name String',
|
|
},
|
|
{
|
|
name: 'nullable',
|
|
field: { type: 'string', nullable: true },
|
|
expected: ' nullable String?',
|
|
},
|
|
{
|
|
name: 'count',
|
|
field: { type: 'int', default: 0 },
|
|
expected: ' count Int @default(0)',
|
|
},
|
|
{
|
|
name: 'enabled',
|
|
field: { type: 'boolean', default: false },
|
|
expected: ' enabled Boolean @default(false)',
|
|
},
|
|
{
|
|
name: 'timestamp',
|
|
field: { type: 'bigint', required: true },
|
|
expected: ' timestamp BigInt',
|
|
},
|
|
{
|
|
name: 'unique',
|
|
field: { type: 'string', unique: true },
|
|
expected: ' unique String @unique',
|
|
},
|
|
])('converts $name field to Prisma', ({ name, field, expected }) => {
|
|
const result = fieldToPrisma(name, field as PackageSchemaField)
|
|
expect(result).toBe(expected)
|
|
})
|
|
})
|
|
|
|
describe('entityToPrisma', () => {
|
|
it('generates complete Prisma model', () => {
|
|
const entity: PackageSchemaEntity = {
|
|
name: 'AuditLog',
|
|
version: '1.0',
|
|
fields: {
|
|
id: { type: 'cuid', primary: true, generated: true },
|
|
tenantId: { type: 'string', required: true },
|
|
action: { type: 'string', required: true },
|
|
timestamp: { type: 'bigint', required: true },
|
|
},
|
|
indexes: [
|
|
{ fields: ['tenantId'] },
|
|
{ fields: ['timestamp'] },
|
|
],
|
|
}
|
|
|
|
const prisma = entityToPrisma(entity)
|
|
|
|
expect(prisma).toContain('model AuditLog {')
|
|
expect(prisma).toContain('id String @id @default(cuid())')
|
|
expect(prisma).toContain('tenantId String')
|
|
expect(prisma).toContain('action String')
|
|
expect(prisma).toContain('timestamp BigInt')
|
|
expect(prisma).toContain('@@index([tenantId])')
|
|
expect(prisma).toContain('@@index([timestamp])')
|
|
expect(prisma).toContain('}')
|
|
})
|
|
|
|
it('generates unique index', () => {
|
|
const entity: PackageSchemaEntity = {
|
|
name: 'Test',
|
|
version: '1.0',
|
|
fields: {
|
|
id: { type: 'cuid', primary: true },
|
|
tenantId: { type: 'string' },
|
|
slug: { type: 'string' },
|
|
},
|
|
indexes: [
|
|
{ fields: ['tenantId', 'slug'], unique: true },
|
|
],
|
|
}
|
|
|
|
const prisma = entityToPrisma(entity)
|
|
expect(prisma).toContain('@@unique([tenantId, slug])')
|
|
})
|
|
|
|
it('generates relations', () => {
|
|
const entity: PackageSchemaEntity = {
|
|
name: 'Post',
|
|
version: '1.0',
|
|
fields: {
|
|
id: { type: 'cuid', primary: true },
|
|
authorId: { type: 'string' },
|
|
},
|
|
relations: [
|
|
{
|
|
name: 'author',
|
|
type: 'belongsTo',
|
|
entity: 'User',
|
|
field: 'authorId',
|
|
onDelete: 'Cascade',
|
|
},
|
|
],
|
|
}
|
|
|
|
const prisma = entityToPrisma(entity)
|
|
expect(prisma).toContain('author User @relation(fields: [authorId], references: [id], onDelete: Cascade)')
|
|
})
|
|
})
|
|
})
|