/** * Edge-case regression tests for three long-standing query/aggregation items * (#26 missing-field predicate, #27 type[]+orderBy first-call completeness, * #24 percentile/median/distinctCount aggregation ops) — verified against the 8.0 engine. */ import { describe, it, expect, beforeEach, afterEach } from 'vitest' import { Brainy } from '../../../src/brainy' import { createTestConfig } from '../../helpers/test-factory' import { NounType } from '../../../src/types/graphTypes' describe('find + aggregation edge cases', () => { let brain: Brainy beforeEach(async () => { brain = new Brainy(createTestConfig()) await brain.init() }) afterEach(async () => { await brain.close() }) // #26 it('find({ where: { field: { missing: true } } }) matches a never-registered field', async () => { const a = await brain.add({ data: 'a', type: NounType.Thing, subtype: 'x', metadata: { name: 'A' } }) const b = await brain.add({ data: 'b', type: NounType.Thing, subtype: 'x', metadata: { name: 'B', status: 'open' } }) // Never-registered field → every entity "misses" it. const neverReg = await brain.find({ where: { neverRegistered: { missing: true } }, limit: 100 }) const neverRegIds = neverReg.map((r) => r.id) expect(neverRegIds).toContain(a) expect(neverRegIds).toContain(b) // Registered field, absent on one entity. const noStatus = await brain.find({ where: { status: { missing: true } }, limit: 100 }) const noStatusIds = noStatus.map((r) => r.id) expect(noStatusIds).toContain(a) // a has no status expect(noStatusIds).not.toContain(b) // b has status }) // #27 it('find({ type: [...], orderBy, limit }) returns the full set on the first call after mutate+query+get', async () => { const ids: string[] = [] for (let i = 0; i < 6; i++) { ids.push( await brain.add({ data: `e${i}`, type: i % 2 === 0 ? NounType.Document : NounType.Person, subtype: 'x', metadata: { n: i } }) ) } await brain.update({ id: ids[0], metadata: { n: 100 }, merge: true }) // mutate await brain.find({ query: 'e' }) // query await brain.get(ids[1]) // get const r = await brain.find({ type: [NounType.Document, NounType.Person], orderBy: 'n', limit: 10 }) expect(r).toHaveLength(6) // all six, not a partial page }) // #24 it('queryAggregate supports percentile (median) and distinctCount', async () => { brain.defineAggregate({ name: 'amounts', source: { type: NounType.Event }, groupBy: ['subtype'], // all 'txn' → one group metrics: { median: { op: 'percentile', field: 'amount', p: 0.5 }, distinctCats: { op: 'distinctCount', field: 'category' } } }) const rows0: Array<[number, string]> = [ [10, 'a'], [20, 'b'], [30, 'a'], [40, 'c'], [50, 'b'] ] for (const [amount, category] of rows0) { await brain.add({ data: 'evt', type: NounType.Event, subtype: 'txn', metadata: { amount, category } }) } const rows = await brain.queryAggregate('amounts', {}) expect(rows.length).toBeGreaterThanOrEqual(1) const m = (rows[0] as any).metrics ?? rows[0] expect(m.median).toBeGreaterThanOrEqual(20) expect(m.median).toBeLessThanOrEqual(40) expect(m.distinctCats).toBe(3) // a, b, c }) })