/** * GROUP BY + 聚合函数测试 (v0.1.2) */ import { MetonaSqlark } from '../src/core'; import { parse } from '../src/sql/parser'; describe('GROUP BY (v0.1.2)', () => { let db: MetonaSqlark; beforeEach(async () => { db = new MetonaSqlark({ name: 'test-groupby', mode: 'memory' }); await db.init(); await db.defineTable('employees', { id: { type: 'string', primaryKey: true }, name: { type: 'string', required: true }, dept: { type: 'string' }, salary: { type: 'number' }, }); await db.table('employees').insertMany([ { id: '1', name: 'Alice', dept: 'Eng', salary: 1000 }, { id: '2', name: 'Bob', dept: 'Eng', salary: 1200 }, { id: '3', name: 'Charlie', dept: 'Sales', salary: 900 }, { id: '4', name: 'Diana', dept: 'Sales', salary: 1100 }, { id: '5', name: 'Eve', dept: 'HR', salary: 800 }, ]); }); afterEach(async () => { await db.close(); }); // =================================================================== // SQL GROUP BY // =================================================================== describe('SQL GROUP BY', () => { it('GROUP BY + COUNT', async () => { const result = await db.query( 'SELECT dept, COUNT(*) FROM employees GROUP BY dept', ) as Record[]; expect(result).toHaveLength(3); const eng = result.find((r: any) => r.dept === 'Eng'); expect(eng!['COUNT(*)']).toBe(2); }); it('GROUP BY + SUM', async () => { const result = await db.query( 'SELECT dept, SUM(salary) FROM employees GROUP BY dept', ) as Record[]; const eng = result.find((r: any) => r.dept === 'Eng'); expect(eng!['SUM(salary)']).toBe(2200); }); it('GROUP BY + AVG', async () => { const result = await db.query( 'SELECT dept, AVG(salary) FROM employees GROUP BY dept', ) as Record[]; const eng = result.find((r: any) => r.dept === 'Eng'); expect(eng!['AVG(salary)']).toBe(1100); }); it('GROUP BY + MIN/MAX', async () => { const result = await db.query( 'SELECT dept, MIN(salary), MAX(salary) FROM employees GROUP BY dept', ) as Record[]; const eng = result.find((r: any) => r.dept === 'Eng'); expect(eng!['MIN(salary)']).toBe(1000); expect(eng!['MAX(salary)']).toBe(1200); }); it('GROUP BY + HAVING', async () => { const result = await db.query( 'SELECT dept, COUNT(*) FROM employees GROUP BY dept HAVING COUNT(*) > 1', ) as Record[]; expect(result).toHaveLength(2); // Eng(2) + Sales(2) }); it('GROUP BY + WHERE + HAVING', async () => { const result = await db.query( "SELECT dept, SUM(salary) FROM employees WHERE dept != 'HR' GROUP BY dept HAVING SUM(salary) > 2000", ) as Record[]; expect(result).toHaveLength(1); // Only Eng }); it('聚合函数别名', async () => { const result = await db.query( 'SELECT dept, COUNT(*) AS cnt, SUM(salary) AS total FROM employees GROUP BY dept', ) as Record[]; const eng = result.find((r: any) => r.dept === 'Eng'); expect(eng!.cnt).toBe(2); expect(eng!.total).toBe(2200); }); }); // =================================================================== // Parser 测试 // =================================================================== describe('Parser', () => { it('解析 COUNT(*)', () => { const ast = parse('SELECT COUNT(*) FROM employees'); expect(ast.columns[0]).toBe('COUNT(*)'); }); it('解析 GROUP BY', () => { const ast = parse('SELECT dept, COUNT(*) FROM employees GROUP BY dept'); expect(ast.groupBy).toEqual(['dept']); }); it('解析 HAVING', () => { const ast = parse('SELECT dept, COUNT(*) FROM employees GROUP BY dept HAVING COUNT(*) > 1'); expect(ast.having).toBeDefined(); }); }); });