213 lines
6.3 KiB
TypeScript
213 lines
6.3 KiB
TypeScript
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 });
|
|
});
|
|
});
|