import { beforeEach, describe, expect, it } from 'bun:test'; import { SimplePostgresClient, SimpleQueryBuilder, SimpleTransactionManager, } from '../src/simple-postgres'; describe('PostgresClient', () => { let client: SimplePostgresClient; const config = { host: 'localhost', port: 5432, database: 'test', user: 'test', password: 'test', max: 10, }; beforeEach(() => { client = new SimplePostgresClient(config); }); describe('query execution', () => { it('should execute simple query', async () => { const result = await client.query('SELECT * FROM users WHERE id = $1', [1]); expect(result).toBeDefined(); expect(result.rows).toBeDefined(); expect(result.rowCount).toBe(0); }); it('should handle empty results', async () => { const result = await client.query('SELECT * FROM invalid'); expect(result.rows).toEqual([]); expect(result.rowCount).toBe(0); }); }); describe('convenience methods', () => { it('should find one record', async () => { await client.insert('users', { name: 'Test' }); const result = await client.findOne('users', { id: 1 }); expect(result).toBeDefined(); expect(result.id).toBe(1); expect(result.name).toBe('Test'); }); it('should find multiple records', async () => { await client.insert('users', { name: 'User 1', active: true }); await client.insert('users', { name: 'User 2', active: true }); await client.insert('users', { name: 'User 3', active: false }); const results = await client.find('users', { active: true }); expect(results).toHaveLength(2); }); it('should insert record', async () => { const result = await client.insert('users', { name: 'New User' }); expect(result).toBeDefined(); expect(result.id).toBe(1); expect(result.name).toBe('New User'); }); it('should update records', async () => { await client.insert('users', { name: 'User 1', active: false }); await client.insert('users', { name: 'User 2', active: false }); const result = await client.update('users', { active: false }, { status: 'inactive' }); expect(result).toBe(2); }); it('should delete records', async () => { await client.insert('users', { name: 'User 1', active: false }); await client.insert('users', { name: 'User 2', active: false }); await client.insert('users', { name: 'User 3', active: true }); const result = await client.delete('users', { active: false }); expect(result).toBe(2); }); }); describe('health check', () => { it('should perform health check', async () => { const health = await client.healthCheck(); expect(health.status).toBe('healthy'); expect(health.isConnected).toBe(true); }); it('should handle disconnection', async () => { await client.disconnect(); // Simple implementation doesn't track connection state in health check const health = await client.healthCheck(); expect(health.status).toBe('healthy'); }); }); describe('connection management', () => { it('should disconnect properly', async () => { await client.disconnect(); // Simple test - just ensure no errors expect(true).toBe(true); }); }); }); describe('QueryBuilder', () => { it('should build SELECT query', () => { const query = new SimpleQueryBuilder() .select(['id', 'name']) .from('users') .where({ active: true }) .orderBy('created_at', 'DESC') .limit(10) .build(); expect(query.text).toContain('SELECT id, name FROM users'); expect(query.text).toContain('WHERE active = $1'); expect(query.text).toContain('ORDER BY created_at DESC'); expect(query.text).toContain('LIMIT 10'); expect(query.values).toEqual([true]); }); it('should build INSERT query', () => { const query = new SimpleQueryBuilder() .insert('users', { name: 'Test', email: 'test@example.com' }) .returning('*') .build(); expect(query.text).toContain('INSERT INTO users'); expect(query.text).toContain('(name, email)'); expect(query.text).toContain('VALUES ($1, $2)'); expect(query.text).toContain('RETURNING *'); expect(query.values).toEqual(['Test', 'test@example.com']); }); it('should build UPDATE query', () => { const date = new Date(); const query = new SimpleQueryBuilder() .update('users') .set({ name: 'Updated', modified: date }) .where({ id: 1 }) .build(); expect(query.text).toContain('UPDATE users SET'); expect(query.text).toContain('name = $1'); expect(query.text).toContain('WHERE id = $3'); expect(query.values).toHaveLength(3); }); it('should build DELETE query', () => { const query = new SimpleQueryBuilder().delete('users').where({ id: 1 }).build(); expect(query.text).toContain('DELETE FROM users'); expect(query.text).toContain('WHERE id = $1'); expect(query.values).toEqual([1]); }); it('should handle joins', () => { const query = new SimpleQueryBuilder() .select(['u.name', 'p.title']) .from('users u') .join('posts p', 'u.id = p.user_id') .where({ 'u.active': true }) .build(); expect(query.text).toContain('JOIN posts p ON u.id = p.user_id'); }); }); describe('TransactionManager', () => { let manager: SimpleTransactionManager; beforeEach(() => { manager = new SimpleTransactionManager({} as any); }); it('should execute transaction successfully', async () => { const result = await manager.transaction(async client => { await client.query('INSERT INTO users (name) VALUES ($1)', ['Test']); return { success: true }; }); expect(result).toEqual({ success: true }); }); it('should rollback on error', async () => { await expect( manager.transaction(async client => { throw new Error('Transaction failed'); }) ).rejects.toThrow('Transaction failed'); }); it('should handle multiple operations', async () => { const result = await manager.transaction(async client => { await client.query('INSERT INTO users VALUES ($1)', ['User 1']); await client.query('INSERT INTO users VALUES ($1)', ['User 2']); return { count: 2 }; }); expect(result).toEqual({ count: 2 }); }); });