UNPKG

adaptus2-orm

Version:

A multi-database ORM supporting MySQL, PostgreSQL, MongoDB, and Snowflake

353 lines (291 loc) 12.8 kB
// tests/orm.test.js const ORM = require('../index'); const { ConfigManager } = require('../src/utils/ConfigManager'); describe('Multi-Database ORM Tests', () => { let configManager; let testConfig; beforeAll(async () => { configManager = new ConfigManager(); // Use test database configuration testConfig = configManager.getConfig('mysql', { host: process.env.TEST_MYSQL_HOST || 'localhost', port: process.env.TEST_MYSQL_PORT || 3306, user: process.env.TEST_MYSQL_USER || 'root', password: process.env.TEST_MYSQL_PASSWORD || 'password', database: process.env.TEST_MYSQL_DATABASE || 'test_orm_db' }); }); afterAll(async () => { // Clean up connections await ORM.cleanup(); }); describe('Connection Management', () => { test('should establish database connection', async () => { const connection = await ORM.getDbConnection(testConfig); expect(connection).toBeDefined(); expect(connection.type).toBe('mysql'); }); test('should reuse existing connection', async () => { const connection1 = await ORM.getDbConnection(testConfig); const connection2 = await ORM.getDbConnection(testConfig); // Should return the same connection instance expect(connection1).toBe(connection2); }); }); describe('Schema Management', () => { const testTable = 'test_users'; afterEach(async () => { // Clean up test table after each test try { await ORM.query(testConfig, `DROP TABLE IF EXISTS ${testTable}`); } catch (error) { // Ignore errors during cleanup } }); test('should create table with schema', async () => { const result = await ORM.createTable(testConfig, testTable, { columns: { id: { type: 'integer', primaryKey: true, autoIncrement: true }, name: { type: 'string', required: true }, email: { type: 'string', required: true, unique: true }, age: { type: 'integer' }, created_at: { type: 'timestamp', default: 'CURRENT_TIMESTAMP' } } }); expect(result.success).toBe(true); }); test('should check if table exists', async () => { // First create the table await ORM.createTable(testConfig, testTable, { columns: { id: { type: 'integer', primaryKey: true } } }); // Check if it exists const exists = await ORM.tableExists(testConfig, testTable); expect(exists.success).toBe(true); expect(exists.data).toBe(true); // Check non-existent table const notExists = await ORM.tableExists(testConfig, 'non_existent_table'); expect(notExists.success).toBe(true); expect(notExists.data).toBe(false); }); }); describe('CRUD Operations', () => { const testTable = 'test_crud_table'; beforeAll(async () => { // Create test table await ORM.createTable(testConfig, testTable, { columns: { id: { type: 'integer', primaryKey: true, autoIncrement: true }, name: { type: 'string', required: true }, email: { type: 'string', required: true }, age: { type: 'integer' } } }); }); afterAll(async () => { // Clean up test table await ORM.query(testConfig, `DROP TABLE IF EXISTS ${testTable}`); }); beforeEach(async () => { // Clear table before each test await ORM.query(testConfig, `TRUNCATE TABLE ${testTable}`); }); test('should create a record', async () => { const result = await ORM.create(testConfig, testTable, { name: 'John Doe', email: 'john@example.com', age: 30 }); expect(result.success).toBe(true); expect(result.data.insertId).toBeDefined(); expect(result.data.record.name).toBe('John Doe'); }); test('should read records', async () => { // Insert test data await ORM.create(testConfig, testTable, { name: 'John Doe', email: 'john@example.com', age: 30 }); await ORM.create(testConfig, testTable, { name: 'Jane Smith', email: 'jane@example.com', age: 25 }); // Read all records const result = await ORM.read(testConfig, testTable); expect(result.success).toBe(true); expect(result.data.length).toBe(2); // Read with conditions const youngUsers = await ORM.read(testConfig, testTable, { where: { age: 25 } }); expect(youngUsers.success).toBe(true); expect(youngUsers.data.length).toBe(1); expect(youngUsers.data[0].name).toBe('Jane Smith'); }); test('should update records', async () => { // Insert test data const user = await ORM.create(testConfig, testTable, { name: 'John Doe', email: 'john@example.com', age: 30 }); // Update the record const result = await ORM.update(testConfig, testTable, { where: { id: user.data.insertId }, data: { age: 31, email: 'john.doe@example.com' } }); expect(result.success).toBe(true); expect(result.data.affectedRows).toBe(1); // Verify update const updated = await ORM.read(testConfig, testTable, { where: { id: user.data.insertId } }); expect(updated.data[0].age).toBe(31); expect(updated.data[0].email).toBe('john.doe@example.com'); }); test('should delete records', async () => { // Insert test data const user = await ORM.create(testConfig, testTable, { name: 'John Doe', email: 'john@example.com', age: 30 }); // Delete the record const result = await ORM.deleteRecord(testConfig, testTable, { where: { id: user.data.insertId } }); expect(result.success).toBe(true); expect(result.data.affectedRows).toBe(1); // Verify deletion const deleted = await ORM.read(testConfig, testTable, { where: { id: user.data.insertId } }); expect(deleted.data.length).toBe(0); }); test('should check if record exists', async () => { // Insert test data await ORM.create(testConfig, testTable, { name: 'John Doe', email: 'john@example.com', age: 30 }); // Check existence const exists = await ORM.exists(testConfig, testTable, { where: { email: 'john@example.com' } }); expect(exists.success).toBe(true); expect(exists.data).toBe(true); // Check non-existence const notExists = await ORM.exists(testConfig, testTable, { where: { email: 'nonexistent@example.com' } }); expect(notExists.success).toBe(true); expect(notExists.data).toBe(false); }); }); describe('Query Builder', () => { const { QueryBuilder } = require('../src/core/QueryBuilder'); test('should build SELECT query', () => { const queryBuilder = QueryBuilder.create('mysql') .table('users') .select(['id', 'name', 'email']) .where('active', true) .orderBy('name', 'ASC') .limit(10); const { sql, params } = queryBuilder.toSQL(); expect(sql).toContain('SELECT id, name, email FROM users'); expect(sql).toContain('WHERE active = ?'); expect(sql).toContain('ORDER BY name ASC'); expect(sql).toContain('LIMIT 10'); expect(params).toEqual([true]); }); test('should build INSERT query', () => { const queryBuilder = QueryBuilder.create('mysql') .table('users') .insert({ name: 'John Doe', email: 'john@example.com', age: 30 }); const { sql, params } = queryBuilder.toSQL(); expect(sql).toContain('INSERT INTO users'); expect(sql).toContain('(name, email, age)'); expect(sql).toContain('VALUES (?, ?, ?)'); expect(params).toEqual(['John Doe', 'john@example.com', 30]); }); test('should build UPDATE query', () => { const queryBuilder = QueryBuilder.create('mysql') .table('users') .update({ age: 31 }) .where('id', 1); const { sql, params } = queryBuilder.toSQL(); expect(sql).toContain('UPDATE users SET age = ?'); expect(sql).toContain('WHERE id = ?'); expect(params).toEqual([31, 1]); }); test('should build DELETE query', () => { const queryBuilder = QueryBuilder.create('mysql') .table('users') .delete() .where('active', false); const { sql, params } = queryBuilder.toSQL(); expect(sql).toContain('DELETE FROM users'); expect(sql).toContain('WHERE active = ?'); expect(params).toEqual([false]); }); }); describe('Error Handling', () => { test('should handle connection errors gracefully', async () => { const badConfig = configManager.getConfig('mysql', { host: 'nonexistent-host', port: 3306, user: 'baduser', password: 'badpassword', database: 'nonexistent' }); try { await ORM.getDbConnection(badConfig); // Should not reach here expect(true).toBe(false); } catch (error) { expect(error).toBeDefined(); } }); test('should handle invalid queries gracefully', async () => { const result = await ORM.query(testConfig, 'INVALID SQL QUERY'); expect(result.success).toBe(false); expect(result.error).toBeDefined(); }); test('should handle duplicate key errors', async () => { const testTable = 'test_duplicate_table'; try { // Create table with unique constraint await ORM.createTable(testConfig, testTable, { columns: { id: { type: 'integer', primaryKey: true }, email: { type: 'string', unique: true } } }); // Insert first record await ORM.create(testConfig, testTable, { id: 1, email: 'duplicate@test.com' }); // Try to insert duplicate const result = await ORM.create(testConfig, testTable, { id: 2, email: 'duplicate@test.com' }); expect(result.success).toBe(false); expect(result.error).toContain('Duplicate'); } finally { // Clean up await ORM.query(testConfig, `DROP TABLE IF EXISTS ${testTable}`); } }); }); });