/** * AriaEngine 并发 + Schema + 事务 + 性能 最终测试 * 全部 MemoryBackend,零卡死 */ import { AriaEngine } from '../../src/engine/aria/index'; import { createSchema } from '../../src/table/schema'; import { MemoryBackend } from '../../src/engine/aria/store/backend'; import { checkFieldType } from '../../src/table/schema'; import { resetOPFSMock } from '../helpers/storage-harness'; beforeEach(() => { resetOPFSMock(); }); describe('AriaEngine — 最终扩展测试', () => { let engine: AriaEngine; beforeEach(async () => { engine = new AriaEngine({ storageBackend: 'memory' }); await engine.open('final-test', 1); }); afterEach(async () => { await engine.close(); }); describe('多表操作', () => { it('创建多表各自CRUD互不干扰', async () => { await engine.createTable(createSchema('t1', { id: { type: 'string', primaryKey: true }, v: { type: 'number' } })); await engine.createTable(createSchema('t2', { id: { type: 'string', primaryKey: true }, v: { type: 'number' } })); await engine.insert('t1', [{ id: 'a', v: 1 }]); await engine.insert('t2', [{ id: 'b', v: 2 }]); expect(await engine.count('t1')).toBe(1); expect(await engine.count('t2')).toBe(1); }); it('删除表后同名重建', async () => { await engine.createTable(createSchema('t', { id: { type: 'string', primaryKey: true }, v: { type: 'number' } })); await engine.dropTable('t'); await engine.createTable(createSchema('t', { id: { type: 'string', primaryKey: true }, x: { type: 'string' } })); const s = await engine.getTableSchema('t'); expect(s!.columns.x).toBeDefined(); expect(s!.columns.v).toBeUndefined(); }); it('getTableNames 返回所有表', async () => { await engine.createTable(createSchema('a', { id: { type: 'string', primaryKey: true } })); await engine.createTable(createSchema('b', { id: { type: 'string', primaryKey: true } })); const names = await engine.getTableNames(); expect(names.sort()).toEqual(['a', 'b']); }); }); describe('类型边界', () => { it('boolean false 存储查询', async () => { await engine.createTable(createSchema('flags', { id: { type: 'string', primaryKey: true }, active: { type: 'boolean' } })); await engine.insert('flags', [{ id: '1', active: false }]); const rows = await engine.find('flags', { table: 'flags', where: { active: false } }); expect(rows).toHaveLength(1); }); it('null JSON 字段', async () => { await engine.createTable(createSchema('docs', { id: { type: 'string', primaryKey: true }, meta: { type: 'json' } })); await engine.insert('docs', [{ id: '1', meta: null as any }]); expect(await engine.count('docs')).toBe(1); }); it('负数存储查询', async () => { await engine.createTable(createSchema('vals', { id: { type: 'string', primaryKey: true }, n: { type: 'number' } })); await engine.insert('vals', [{ id: '1', n: -42 }]); const rows = await engine.find('vals', { table: 'vals' }); expect(rows[0].n).toBe(-42); }); it('零值存储查询', async () => { await engine.createTable(createSchema('vals2', { id: { type: 'string', primaryKey: true }, n: { type: 'number', default: 0 } })); await engine.insert('vals2', [{ id: '1', n: 0 }]); const rows = await engine.find('vals2', { table: 'vals2' }); expect(rows[0].n).toBe(0); }); }); describe('查询边界', () => { beforeEach(async () => { await engine.createTable(createSchema('items', { id: { type: 'string', primaryKey: true }, price: { type: 'number' }, qty: { type: 'number' }, })); for (let i = 0; i < 20; i++) { await engine.insert('items', [{ id: `${i}`, price: i * 10, qty: i }]); } }); it('count with $or where', async () => { const c = await engine.count('items', { table: 'items', where: { $or: [{ price: 0 }, { price: 190 }] } }); expect(c).toBe(2); }); it('count with $gt where', async () => { const c = await engine.count('items', { table: 'items', where: { price: { $gt: 100 } } }); expect(c).toBe(9); // 110~190 = 9 items }); it('find with $and and $or', async () => { const rows = await engine.find('items', { table: 'items', where: { $and: [{ price: { $gt: 50 } }, { $or: [{ qty: 6 }, { qty: 10 }] }] } }); expect(rows).toHaveLength(2); }); it('单列排序 + limit', async () => { const rows = await engine.find('items', { table: 'items', orderBy: [{ column: 'price', direction: 'desc' }], limit: 5 }); expect(rows[0].price).toBe(190); }); it('无匹配 update 返回 0', async () => { const c = await engine.update('items', { table: 'items', where: { id: 'nonexistent' } }, { price: 999 }); expect(c).toBe(0); }); it('无匹配 delete 返回 0', async () => { const c = await engine.delete('items', { table: 'items', where: { id: 'nonexistent' } }); expect(c).toBe(0); }); it('全表 update', async () => { const c = await engine.update('items', { table: 'items' }, { qty: 100 }); expect(c).toBe(20); }); it('全表 delete', async () => { const c = await engine.delete('items', { table: 'items' }); expect(c).toBe(20); expect(await engine.count('items')).toBe(0); }); }); describe('MemoryBackend 直接测试', () => { it('read 不存在的 key 返回 null', async () => { const be = new MemoryBackend(); await be.open('test'); expect(await be.read('nokey')).toBeNull(); await be.close(); }); it('write+read 往返', async () => { const be = new MemoryBackend(); await be.open('test2'); const data = new TextEncoder().encode('hello').buffer; await be.write('k', data); const read = await be.read('k'); expect(new TextDecoder().decode(read!)).toBe('hello'); await be.close(); }); it('exists 检测', async () => { const be = new MemoryBackend(); await be.open('test3'); expect(await be.exists('k')).toBe(false); await be.write('k', new ArrayBuffer(4)); expect(await be.exists('k')).toBe(true); await be.close(); }); it('delete 删除', async () => { const be = new MemoryBackend(); await be.open('test4'); await be.write('k', new ArrayBuffer(4)); await be.delete('k'); expect(await be.exists('k')).toBe(false); await be.close(); }); it('listKeys 列出所有 key', async () => { const be = new MemoryBackend(); await be.open('test5'); await be.write('a', new ArrayBuffer(1)); await be.write('b', new ArrayBuffer(1)); const keys = await be.listKeys(); expect(keys.sort()).toEqual(['a', 'b']); await be.close(); }); it('clear 清空', async () => { const be = new MemoryBackend(); await be.open('test6'); await be.write('a', new ArrayBuffer(1)); await be.clear(); expect(await be.listKeys()).toHaveLength(0); await be.close(); }); }); describe('checkFieldType 约束全覆盖', () => { it('maxLength=0 拒绝任何非空字符串', () => { expect(() => checkFieldType('t','c','string','x', { type:'string',maxLength:0 })).toThrow('exceeds max length'); }); it('min=max 限定精确值', () => { expect(() => checkFieldType('t','c','number',5, { type:'number',min:5,max:5 })).not.toThrow(); expect(() => checkFieldType('t','c','number',4, { type:'number',min:5,max:5 })).toThrow('below minimum'); }); it('无 colDef 时不校验约束', () => { expect(() => checkFieldType('t','c','string','anylength')).not.toThrow(); }); it('boolean 不受 min/max 约束', () => { expect(() => checkFieldType('t','c','boolean',true, { type:'boolean',min:0,max:1 } as any)).not.toThrow(); }); }); });