Skip to main content
Glama
DatabaseSchema.test.js11.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const vitest_1 = require("vitest"); const Environment_1 = require("../value-objects/Environment"); const Column_1 = require("./Column"); const ForeignKey_1 = require("./ForeignKey"); const DatabaseSchema_1 = require("./DatabaseSchema"); const TableInfo_1 = require("./TableInfo"); (0, vitest_1.describe)('DatabaseSchema', () => { let testDate; let usersTable; let postsTable; (0, vitest_1.beforeEach)(() => { testDate = new Date('2025-01-01T12:00:00Z'); usersTable = new TableInfo_1.TableInfo('users', 'table', [new Column_1.Column('id', 'INTEGER', true), new Column_1.Column('name', 'TEXT')]); postsTable = new TableInfo_1.TableInfo('posts', 'table', [ new Column_1.Column('id', 'INTEGER', true), new Column_1.Column('user_id', 'INTEGER'), new Column_1.Column('title', 'TEXT'), ], [], [new ForeignKey_1.ForeignKey('posts', 'user_id', 'users', 'id', 'CASCADE')]); }); (0, vitest_1.describe)('constructor', () => { (0, vitest_1.it)('should create schema with all properties', () => { const schema = new DatabaseSchema_1.DatabaseSchema('my_database', Environment_1.Environment.DEVELOPMENT, [usersTable, postsTable], testDate); (0, vitest_1.expect)(schema.name).toBe('my_database'); (0, vitest_1.expect)(schema.environment).toBe(Environment_1.Environment.DEVELOPMENT); (0, vitest_1.expect)(schema.tables.length).toBe(2); (0, vitest_1.expect)(schema.fetchedAt).toBe(testDate); }); (0, vitest_1.it)('should trim database name', () => { const schema = new DatabaseSchema_1.DatabaseSchema(' my_database ', Environment_1.Environment.PRODUCTION, [usersTable], testDate); (0, vitest_1.expect)(schema.name).toBe('my_database'); }); (0, vitest_1.it)('should throw error for empty database name', () => { (0, vitest_1.expect)(() => new DatabaseSchema_1.DatabaseSchema('', Environment_1.Environment.DEVELOPMENT, [usersTable], testDate)).toThrow('Database name cannot be empty'); }); (0, vitest_1.it)('should throw error for empty tables array', () => { (0, vitest_1.expect)(() => new DatabaseSchema_1.DatabaseSchema('db', Environment_1.Environment.DEVELOPMENT, [], testDate)).toThrow('Database must have at least one table'); }); (0, vitest_1.it)('should be immutable', () => { const schema = new DatabaseSchema_1.DatabaseSchema('db', Environment_1.Environment.DEVELOPMENT, [usersTable], testDate); (0, vitest_1.expect)(Object.isFrozen(schema)).toBe(true); (0, vitest_1.expect)(Object.isFrozen(schema.tables)).toBe(true); }); }); (0, vitest_1.describe)('getTable()', () => { (0, vitest_1.it)('should return table by name', () => { const schema = new DatabaseSchema_1.DatabaseSchema('db', Environment_1.Environment.DEVELOPMENT, [usersTable], testDate); const table = schema.getTable('users'); (0, vitest_1.expect)(table).toBeDefined(); (0, vitest_1.expect)(table?.name).toBe('users'); }); (0, vitest_1.it)('should return undefined for non-existent table', () => { const schema = new DatabaseSchema_1.DatabaseSchema('db', Environment_1.Environment.DEVELOPMENT, [usersTable], testDate); (0, vitest_1.expect)(schema.getTable('nonexistent')).toBeUndefined(); }); }); (0, vitest_1.describe)('getTablesThatReference()', () => { (0, vitest_1.it)('should return tables that reference specified table', () => { const schema = new DatabaseSchema_1.DatabaseSchema('db', Environment_1.Environment.DEVELOPMENT, [usersTable, postsTable], testDate); const referencingTables = schema.getTablesThatReference('users'); (0, vitest_1.expect)(referencingTables.length).toBe(1); (0, vitest_1.expect)(referencingTables[0].name).toBe('posts'); }); (0, vitest_1.it)('should return empty array when no tables reference specified table', () => { const schema = new DatabaseSchema_1.DatabaseSchema('db', Environment_1.Environment.DEVELOPMENT, [usersTable], testDate); const referencingTables = schema.getTablesThatReference('users'); (0, vitest_1.expect)(referencingTables).toEqual([]); }); }); (0, vitest_1.describe)('getTablesReferencedBy()', () => { (0, vitest_1.it)('should return tables referenced by specified table', () => { const schema = new DatabaseSchema_1.DatabaseSchema('db', Environment_1.Environment.DEVELOPMENT, [usersTable, postsTable], testDate); const referenced = schema.getTablesReferencedBy('posts'); (0, vitest_1.expect)(referenced).toEqual(['users']); }); (0, vitest_1.it)('should return empty array when table has no references', () => { const schema = new DatabaseSchema_1.DatabaseSchema('db', Environment_1.Environment.DEVELOPMENT, [usersTable, postsTable], testDate); const referenced = schema.getTablesReferencedBy('users'); (0, vitest_1.expect)(referenced).toEqual([]); }); (0, vitest_1.it)('should return empty array for non-existent table', () => { const schema = new DatabaseSchema_1.DatabaseSchema('db', Environment_1.Environment.DEVELOPMENT, [usersTable], testDate); const referenced = schema.getTablesReferencedBy('nonexistent'); (0, vitest_1.expect)(referenced).toEqual([]); }); }); (0, vitest_1.describe)('getTableCount()', () => { (0, vitest_1.it)('should return table count', () => { const schema = new DatabaseSchema_1.DatabaseSchema('db', Environment_1.Environment.DEVELOPMENT, [usersTable, postsTable], testDate); (0, vitest_1.expect)(schema.getTableCount()).toBe(2); }); }); (0, vitest_1.describe)('getTablesWithoutPrimaryKey()', () => { (0, vitest_1.it)('should return tables without primary keys', () => { const noPkTable = new TableInfo_1.TableInfo('logs', 'table', [new Column_1.Column('message', 'TEXT')]); const schema = new DatabaseSchema_1.DatabaseSchema('db', Environment_1.Environment.DEVELOPMENT, [usersTable, noPkTable], testDate); const tables = schema.getTablesWithoutPrimaryKey(); (0, vitest_1.expect)(tables.length).toBe(1); (0, vitest_1.expect)(tables[0].name).toBe('logs'); }); (0, vitest_1.it)('should return empty array when all tables have primary keys', () => { const schema = new DatabaseSchema_1.DatabaseSchema('db', Environment_1.Environment.DEVELOPMENT, [usersTable], testDate); (0, vitest_1.expect)(schema.getTablesWithoutPrimaryKey()).toEqual([]); }); }); (0, vitest_1.describe)('getTablesWithForeignKeys()', () => { (0, vitest_1.it)('should return tables with foreign keys', () => { const schema = new DatabaseSchema_1.DatabaseSchema('db', Environment_1.Environment.DEVELOPMENT, [usersTable, postsTable], testDate); const tables = schema.getTablesWithForeignKeys(); (0, vitest_1.expect)(tables.length).toBe(1); (0, vitest_1.expect)(tables[0].name).toBe('posts'); }); (0, vitest_1.it)('should return empty array when no tables have foreign keys', () => { const schema = new DatabaseSchema_1.DatabaseSchema('db', Environment_1.Environment.DEVELOPMENT, [usersTable], testDate); (0, vitest_1.expect)(schema.getTablesWithForeignKeys()).toEqual([]); }); }); (0, vitest_1.describe)('getViews()', () => { (0, vitest_1.it)('should return all views', () => { const view = new TableInfo_1.TableInfo('user_view', 'view', [new Column_1.Column('id', 'INTEGER')]); const schema = new DatabaseSchema_1.DatabaseSchema('db', Environment_1.Environment.DEVELOPMENT, [usersTable, view], testDate); const views = schema.getViews(); (0, vitest_1.expect)(views.length).toBe(1); (0, vitest_1.expect)(views[0].name).toBe('user_view'); }); (0, vitest_1.it)('should return empty array when no views', () => { const schema = new DatabaseSchema_1.DatabaseSchema('db', Environment_1.Environment.DEVELOPMENT, [usersTable], testDate); (0, vitest_1.expect)(schema.getViews()).toEqual([]); }); }); (0, vitest_1.describe)('getBaseTables()', () => { (0, vitest_1.it)('should return all base tables (non-views)', () => { const view = new TableInfo_1.TableInfo('user_view', 'view', [new Column_1.Column('id', 'INTEGER')]); const schema = new DatabaseSchema_1.DatabaseSchema('db', Environment_1.Environment.DEVELOPMENT, [usersTable, view], testDate); const tables = schema.getBaseTables(); (0, vitest_1.expect)(tables.length).toBe(1); (0, vitest_1.expect)(tables[0].name).toBe('users'); }); }); (0, vitest_1.describe)('isFresh()', () => { (0, vitest_1.it)('should return true for freshly fetched schema', () => { const now = new Date(); const schema = new DatabaseSchema_1.DatabaseSchema('db', Environment_1.Environment.DEVELOPMENT, [usersTable], now); (0, vitest_1.expect)(schema.isFresh(10)).toBe(true); }); (0, vitest_1.it)('should return false for stale schema', () => { const old = new Date(Date.now() - 15 * 60 * 1000); // 15 minutes ago const schema = new DatabaseSchema_1.DatabaseSchema('db', Environment_1.Environment.DEVELOPMENT, [usersTable], old); (0, vitest_1.expect)(schema.isFresh(10)).toBe(false); }); (0, vitest_1.it)('should use 10 minutes as default freshness threshold', () => { const old = new Date(Date.now() - 11 * 60 * 1000); // 11 minutes ago const schema = new DatabaseSchema_1.DatabaseSchema('db', Environment_1.Environment.DEVELOPMENT, [usersTable], old); (0, vitest_1.expect)(schema.isFresh()).toBe(false); }); }); (0, vitest_1.describe)('getAgeInMinutes()', () => { (0, vitest_1.it)('should return age in minutes', () => { const tenMinutesAgo = new Date(Date.now() - 10 * 60 * 1000); const schema = new DatabaseSchema_1.DatabaseSchema('db', Environment_1.Environment.DEVELOPMENT, [usersTable], tenMinutesAgo); const age = schema.getAgeInMinutes(); (0, vitest_1.expect)(age).toBeGreaterThanOrEqual(9.9); (0, vitest_1.expect)(age).toBeLessThanOrEqual(10.1); }); }); (0, vitest_1.describe)('semantic intent preservation', () => { (0, vitest_1.it)('should preserve environment semantic', () => { const prodSchema = new DatabaseSchema_1.DatabaseSchema('db', Environment_1.Environment.PRODUCTION, [usersTable], testDate); const devSchema = new DatabaseSchema_1.DatabaseSchema('db', Environment_1.Environment.DEVELOPMENT, [usersTable], testDate); (0, vitest_1.expect)(prodSchema.environment).toBe(Environment_1.Environment.PRODUCTION); (0, vitest_1.expect)(devSchema.environment).toBe(Environment_1.Environment.DEVELOPMENT); }); }); }); //# sourceMappingURL=DatabaseSchema.test.js.map

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/semanticintent/semantic-d1-mcp'

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