Skip to main content
Glama
generate-dataset.test.ts14.7 kB
import { describe, it, expect } from 'vitest'; import type { DatasetSchema } from '../../src/types/schema.js'; import { EntityType, RelationshipType } from '../../src/types/schema.js'; describe('generate-dataset contract tests', () => { describe('input schema validation', () => { it('should accept valid dataset schema with single entity', () => { const schema: DatasetSchema = { entities: { users: { count: 10, type: EntityType.PERSON, }, }, }; // This test will validate against the Zod schema once implemented expect(schema).toBeDefined(); expect(schema.entities['users']?.count).toBe(10); expect(schema.entities['users']?.type).toBe(EntityType.PERSON); }); it('should accept valid dataset schema with multiple entities', () => { const schema: DatasetSchema = { entities: { users: { count: 10, type: EntityType.PERSON, }, companies: { count: 5, type: EntityType.COMPANY, }, }, }; expect(schema).toBeDefined(); expect(Object.keys(schema.entities)).toHaveLength(2); }); it('should accept schema with relationships', () => { const schema: DatasetSchema = { entities: { users: { count: 10, type: EntityType.PERSON, }, orders: { count: 50, type: EntityType.CUSTOM, fields: ['id', 'amount', 'date', 'userId'], relationships: { userId: { references: 'users', type: RelationshipType.ONE_TO_MANY, }, }, }, }, }; expect(schema).toBeDefined(); expect(schema.entities['orders']?.relationships).toBeDefined(); expect(schema.entities['orders']?.relationships?.['userId']?.references).toBe('users'); }); it('should accept schema with optional fields', () => { const schema: DatasetSchema = { entities: { users: { count: 10, type: EntityType.PERSON, fields: ['id', 'name', 'email'], }, }, }; expect(schema).toBeDefined(); expect(schema.entities['users']?.fields).toEqual(['id', 'name', 'email']); }); it('should accept schema with nullable relationships', () => { const schema: DatasetSchema = { entities: { users: { count: 10, type: EntityType.PERSON, }, orders: { count: 50, type: EntityType.CUSTOM, fields: ['id', 'userId'], relationships: { userId: { references: 'users', type: RelationshipType.ONE_TO_MANY, nullable: true, }, }, }, }, }; expect(schema.entities['orders']?.relationships?.['userId']?.nullable).toBe(true); }); it('should reject schema with circular dependencies', () => { const schema: DatasetSchema = { entities: { users: { count: 10, type: EntityType.PERSON, relationships: { profileId: { references: 'profiles', type: RelationshipType.ONE_TO_MANY, }, }, }, profiles: { count: 10, type: EntityType.CUSTOM, fields: ['id', 'userId'], relationships: { userId: { references: 'users', type: RelationshipType.ONE_TO_MANY, }, }, }, }, }; // Will be tested once validation is implemented expect(schema).toBeDefined(); }); it('should reject schema with non-existent entity references', () => { const schema: DatasetSchema = { entities: { orders: { count: 50, type: EntityType.CUSTOM, fields: ['id', 'userId'], relationships: { userId: { references: 'users', // users entity doesn't exist type: RelationshipType.ONE_TO_MANY, }, }, }, }, }; // Will be tested once validation is implemented expect(schema).toBeDefined(); }); it('should accept schema with count up to 10000', () => { const schema: DatasetSchema = { entities: { users: { count: 10000, type: EntityType.PERSON, }, }, }; expect(schema.entities['users']?.count).toBe(10000); }); it('should reject schema with count exceeding 10000', () => { const schema: DatasetSchema = { entities: { users: { count: 10001, type: EntityType.PERSON, }, }, }; // Will be tested once validation is implemented expect(schema).toBeDefined(); }); it('should accept schema with seed for reproducibility', () => { const params = { schema: { entities: { users: { count: 10, type: EntityType.PERSON, }, }, }, seed: 12345, }; expect(params.seed).toBe(12345); }); it('should accept schema with locale parameter', () => { const params = { schema: { entities: { users: { count: 10, type: EntityType.PERSON, }, }, }, locale: 'fr', }; expect(params.locale).toBe('fr'); }); }); describe('output format validation', () => { it('should return dataset with all requested entities', () => { // Expected output structure const expectedOutput = { dataset: { users: [ { id: 'user_1', firstName: 'John', lastName: 'Doe', email: 'john.doe@example.com', }, ], companies: [ { id: 'company_1', name: 'Acme Corp', industry: 'Technology', }, ], }, metadata: { entityCounts: { users: 1, companies: 1, }, totalRecords: 2, seed: expect.any(Number) as number, }, }; // Structure validation expect(expectedOutput.dataset).toBeDefined(); expect(expectedOutput.metadata).toBeDefined(); expect(expectedOutput.metadata.entityCounts).toBeDefined(); expect(expectedOutput.metadata.totalRecords).toBe(2); }); it('should return entities in correct dependency order', () => { // Parent entities should appear before children const expectedOutput = { dataset: { users: [], // Parent orders: [], // Child (references users) }, }; const keys = Object.keys(expectedOutput.dataset); expect(keys[0]).toBe('users'); expect(keys[1]).toBe('orders'); }); it('should include valid foreign key references', () => { // Expected order structure with FK const expectedOrder = { id: 'order_1', amount: 100.5, userId: 'user_1', // Must reference existing user }; expect(expectedOrder.userId).toMatch(/^user_\d+$/); }); it('should include metadata with entity counts', () => { const expectedMetadata = { entityCounts: { users: 10, orders: 50, }, totalRecords: 60, seed: 12345, }; expect(expectedMetadata.entityCounts).toBeDefined(); expect(expectedMetadata.totalRecords).toBe(60); expect(expectedMetadata.seed).toBe(12345); }); it('should support nullable foreign keys', () => { const expectedOrder = { id: 'order_1', amount: 100.5, userId: null, // nullable FK }; expect(expectedOrder.userId).toBeNull(); }); }); describe('referential integrity validation', () => { it('should ensure all foreign keys reference existing entities', () => { // Simulated dataset const dataset = { users: [ { id: 'user_1', name: 'Alice' }, { id: 'user_2', name: 'Bob' }, ], orders: [ { id: 'order_1', userId: 'user_1' }, { id: 'order_2', userId: 'user_2' }, { id: 'order_3', userId: 'user_1' }, ], }; const userIds = dataset.users.map((u) => u.id); dataset.orders.forEach((order) => { expect(userIds).toContain(order.userId); }); }); it('should handle many-to-many relationships correctly', () => { // Multiple orders can reference same user const dataset = { users: [{ id: 'user_1', name: 'Alice' }], orders: [ { id: 'order_1', userId: 'user_1' }, { id: 'order_2', userId: 'user_1' }, { id: 'order_3', userId: 'user_1' }, ], }; const userIds = new Set(dataset.orders.map((o) => o.userId)); expect(userIds.size).toBe(1); // All orders reference same user expect(userIds.has('user_1')).toBe(true); }); it('should handle many-to-many relationships correctly', () => { // Many-to-many junction table const dataset = { users: [ { id: 'user_1', name: 'Alice' }, { id: 'user_2', name: 'Bob' }, ], products: [ { id: 'product_1', name: 'Widget' }, { id: 'product_2', name: 'Gadget' }, ], userProducts: [ { userId: 'user_1', productId: 'product_1' }, { userId: 'user_1', productId: 'product_2' }, { userId: 'user_2', productId: 'product_1' }, ], }; const userIds = dataset.users.map((u) => u.id); const productIds = dataset.products.map((p) => p.id); dataset.userProducts.forEach((up) => { expect(userIds).toContain(up.userId); expect(productIds).toContain(up.productId); }); }); it('should handle nullable relationships with null values', () => { const dataset = { users: [{ id: 'user_1', name: 'Alice' }], orders: [ { id: 'order_1', userId: 'user_1' }, { id: 'order_2', userId: null }, ], }; const userIds = dataset.users.map((u) => u.id); dataset.orders.forEach((order) => { if (order.userId !== null) { expect(userIds).toContain(order.userId); } }); }); it('should maintain referential integrity across complex schemas', () => { const dataset = { companies: [{ id: 'company_1', name: 'Acme' }], users: [ { id: 'user_1', companyId: 'company_1' }, { id: 'user_2', companyId: 'company_1' }, ], orders: [ { id: 'order_1', userId: 'user_1' }, { id: 'order_2', userId: 'user_2' }, ], }; // Validate company references const companyIds = dataset.companies.map((c) => c.id); dataset.users.forEach((user) => { expect(companyIds).toContain(user.companyId); }); // Validate user references const userIds = dataset.users.map((u) => u.id); dataset.orders.forEach((order) => { expect(userIds).toContain(order.userId); }); }); }); describe('seed reproducibility', () => { it('should generate identical datasets with same seed', () => { // This will be tested once generator is implemented const seed = 12345; // First generation const params1 = { schema: { entities: { users: { count: 10, type: EntityType.PERSON, }, }, }, seed, }; // Second generation with same seed const params2 = { schema: { entities: { users: { count: 10, type: EntityType.PERSON, }, }, }, seed, }; expect(params1.seed).toBe(params2.seed); }); it('should generate different datasets with different seeds', () => { const params1 = { schema: { entities: { users: { count: 10, type: EntityType.PERSON, }, }, }, seed: 12345, }; const params2 = { schema: { entities: { users: { count: 10, type: EntityType.PERSON, }, }, }, seed: 67890, }; expect(params1.seed).not.toBe(params2.seed); }); }); describe('multi-entity support', () => { it('should generate multiple entity types in single dataset', () => { const schema: DatasetSchema = { entities: { users: { count: 10, type: EntityType.PERSON, }, companies: { count: 5, type: EntityType.COMPANY, }, orders: { count: 50, type: EntityType.CUSTOM, fields: ['id', 'amount', 'userId'], }, }, }; expect(Object.keys(schema.entities)).toHaveLength(3); expect(schema.entities['users']?.type).toBe(EntityType.PERSON); expect(schema.entities['companies']?.type).toBe(EntityType.COMPANY); expect(schema.entities['orders']?.type).toBe(EntityType.CUSTOM); }); it('should respect entity count limits per entity', () => { const schema: DatasetSchema = { entities: { users: { count: 100, type: EntityType.PERSON, }, orders: { count: 1000, type: EntityType.CUSTOM, fields: ['id', 'userId'], }, }, }; expect(schema.entities['users']?.count).toBe(100); expect(schema.entities['orders']?.count).toBe(1000); }); it('should handle custom entity types with custom fields', () => { const schema: DatasetSchema = { entities: { products: { count: 20, type: EntityType.CUSTOM, fields: ['id', 'name', 'price', 'sku', 'category'], }, }, }; expect(schema.entities['products']?.type).toBe(EntityType.CUSTOM); expect(schema.entities['products']?.fields).toHaveLength(5); expect(schema.entities['products']?.fields).toContain('sku'); }); }); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/funsjanssen/faker-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server