kimi-code/packages/minidb/test/query-engine.test.ts
haozhe.yang ca5aea91b6 feat(minidb): add embedded key-value database package
- add @moonshot-ai/minidb: pure-Node.js embedded KV store mixing
  Redis-style in-memory access with WAL + snapshot persistence
- implement core engine: codec, store, wal, snapshot, recovery,
  compaction, lockfile, skiplist
- add indexing: dt-index, compound-index, text-index/postings,
  index-manager, query engine
- add server, value-reader, crc32 utilities
- include unit/e2e tests plus fuzz/crash-recovery/soak suites and
  session-store benchmarks
- register package in flake.nix and pnpm-lock.yaml
2026-06-28 16:30:10 +08:00

192 lines
8.2 KiB
TypeScript

// Drives the query engine through the real db.query() path to cover the
// operators and path handling that the higher-level tests do not exercise.
import { test } from 'vitest';
import assert from 'node:assert/strict';
import fs from 'node:fs/promises';
import os from 'node:os';
import path from 'node:path';
import { MiniDb } from '../src/index.js';
async function tmpDir() {
return fs.mkdtemp(path.join(os.tmpdir(), 'minidb-qe-'));
}
async function seed() {
const dir = await tmpDir();
const db = await MiniDb.open({ dir, valueCodec: 'json' });
await db.set('a', { name: 'Ann', age: 30, city: 'Paris', tags: ['x', 'y'], score: 9.5, active: true });
await db.set('b', { name: 'Bob', age: 17, city: 'London', tags: ['y'], score: 4.2, active: false });
await db.set('c', { name: 'Eve', age: 25, city: 'Paris', tags: ['z'], score: 7.0 });
await db.set('d', { name: 'Max', age: 40, city: 'Berlin', tags: [], score: 8.1, active: true });
return { dir, db };
}
test('comparison operators $eq $ne $gt $gte $lt $lte', async () => {
const { dir, db } = await seed();
try {
assert.deepEqual(db.query({ filter: { age: { $eq: 25 } } }).map((r) => r.key), ['c']);
assert.deepEqual(db.query({ filter: { age: { $ne: 25 } } }).map((r) => r.key).sort(), ['a', 'b', 'd']);
assert.deepEqual(db.query({ filter: { age: { $gte: 30 } } }).map((r) => r.key).sort(), ['a', 'd']);
assert.deepEqual(db.query({ filter: { age: { $lte: 25 } } }).map((r) => r.key).sort(), ['b', 'c']);
// Combine two operators in one cond object (both must hold).
assert.deepEqual(
db.query({ filter: { age: { $gt: 17, $lt: 30 } } }).map((r) => r.key),
['c'],
);
await db.close();
} finally {
await fs.rm(dir, { recursive: true, force: true });
}
});
test('$in / $nin membership', async () => {
const { dir, db } = await seed();
try {
assert.deepEqual(db.query({ filter: { city: { $in: ['Paris', 'Berlin'] } } }).map((r) => r.key).sort(), [
'a',
'c',
'd',
]);
assert.deepEqual(db.query({ filter: { city: { $nin: ['Paris'] } } }).map((r) => r.key).sort(), ['b', 'd']);
// Non-array argument never matches.
assert.deepEqual(db.query({ filter: { city: { $in: 'Paris' as unknown as string[] } } }).map((r) => r.key), []);
assert.deepEqual(db.query({ filter: { city: { $nin: 'Paris' as unknown as string[] } } }).map((r) => r.key), []);
await db.close();
} finally {
await fs.rm(dir, { recursive: true, force: true });
}
});
test('$exists and $type', async () => {
const { dir, db } = await seed();
try {
// 'active' is set on a, b, d but not c.
assert.deepEqual(db.query({ filter: { active: { $exists: true } } }).map((r) => r.key).sort(), ['a', 'b', 'd']);
assert.deepEqual(db.query({ filter: { active: { $exists: false } } }).map((r) => r.key), ['c']);
assert.deepEqual(db.query({ filter: { name: { $type: 'string' } } }).map((r) => r.key).sort(), [
'a',
'b',
'c',
'd',
]);
assert.deepEqual(db.query({ filter: { age: { $type: 'string' } } }).map((r) => r.key), []);
await db.close();
} finally {
await fs.rm(dir, { recursive: true, force: true });
}
});
test('$regex with string, [pattern, flags], RegExp and stateful global RegExp', async () => {
const { dir, db } = await seed();
try {
assert.deepEqual(db.query({ filter: { name: { $regex: '^A' } } }).map((r) => r.key), ['a']);
// Tuple form supplies flags.
assert.deepEqual(
db.query({ filter: { name: { $regex: ['^a', 'i'] as unknown as string } } }).map((r) => r.key),
['a'],
);
// RegExp instance form.
assert.deepEqual(db.query({ filter: { name: { $regex: /^B/ } } }).map((r) => r.key), ['b']);
// A global RegExp is stateful; the engine must reset lastIndex so every
// document is tested from the start.
const g = /^E/g;
assert.deepEqual(db.query({ filter: { name: { $regex: g } } }).map((r) => r.key), ['c']);
// Non-string field never matches a regex.
assert.deepEqual(db.query({ filter: { age: { $regex: '3' } } }).map((r) => r.key), []);
await db.close();
} finally {
await fs.rm(dir, { recursive: true, force: true });
}
});
test('scalar RegExp value resets lastIndex between documents', async () => {
const { dir, db } = await seed();
try {
const g = /^A/g;
assert.deepEqual(db.query({ filter: { name: g } }).map((r) => r.key), ['a']);
// Non-string value against a scalar RegExp never matches.
assert.deepEqual(db.query({ filter: { age: /^3/ } }).map((r) => r.key), []);
await db.close();
} finally {
await fs.rm(dir, { recursive: true, force: true });
}
});
test('logical operators $and $or $nor $not', async () => {
const { dir, db } = await seed();
try {
assert.deepEqual(
db.query({ filter: { $and: [{ city: 'Paris' }, { age: { $gt: 20 } }] } }).map((r) => r.key).sort(),
['a', 'c'],
);
assert.deepEqual(
db.query({ filter: { $or: [{ name: 'Ann' }, { name: 'Bob' }] } }).map((r) => r.key).sort(),
['a', 'b'],
);
// $nor: matches documents that satisfy NONE of the branches.
assert.deepEqual(
db.query({ filter: { $nor: [{ city: 'Paris' }, { city: 'London' }] } }).map((r) => r.key),
['d'],
);
assert.deepEqual(db.query({ filter: { $not: { city: 'Paris' } } }).map((r) => r.key).sort(), ['b', 'd']);
await db.close();
} finally {
await fs.rm(dir, { recursive: true, force: true });
}
});
test('unknown operator and non-array logical args never match', async () => {
const { dir, db } = await seed();
try {
// Unknown operator falls through to the default case (no match).
assert.deepEqual(db.query({ filter: { age: { $bogus: 1 } as never } }).map((r) => r.key), []);
// $and/$or/$nor with a non-array argument are treated as non-matching.
assert.deepEqual(db.query({ filter: { $and: { city: 'Paris' } as never } }).map((r) => r.key), []);
assert.deepEqual(db.query({ filter: { $or: { city: 'Paris' } as never } }).map((r) => r.key), []);
assert.deepEqual(db.query({ filter: { $nor: { city: 'Paris' } as never } }).map((r) => r.key), []);
await db.close();
} finally {
await fs.rm(dir, { recursive: true, force: true });
}
});
test('nested dot + bracket paths in filter and projection', async () => {
const dir = await tmpDir();
try {
const db = await MiniDb.open({ dir, valueCodec: 'json' });
await db.set('p1', { user: { name: 'Ann', addr: { zip: '75001' } }, items: [{ sku: 'A' }, { sku: 'B' }] });
await db.set('p2', { user: { name: 'Bob', addr: { zip: '12345' } }, items: [{ sku: 'A' }] });
await db.set('p3', { user: { name: 'Eve' }, items: [] });
assert.deepEqual(db.query({ filter: { 'user.name': 'Bob' } }).map((r) => r.key), ['p2']);
assert.deepEqual(db.query({ filter: { 'user.addr.zip': '75001' } }).map((r) => r.key), ['p1']);
// Bracket index into an array element.
assert.deepEqual(db.query({ filter: { 'items[1].sku': 'B' } }).map((r) => r.key), ['p1']);
// Missing intermediate path does not match.
assert.deepEqual(db.query({ filter: { 'user.addr.zip': 'x' } }).map((r) => r.key).length, 0);
// Nested projection rebuilds the nested shape in the output.
const projected = db.query({ filter: { 'user.name': 'Ann' }, project: ['user.addr.zip', 'items[0].sku'] });
assert.deepEqual(projected[0]!.value, { user: { addr: { zip: '75001' } }, items: [{ sku: 'A' }] });
// Projecting a missing path drops it; empty project list returns the doc.
assert.deepEqual(db.query({ project: [] })[0]!.value, (await db.get('p1')));
await db.close();
} finally {
await fs.rm(dir, { recursive: true, force: true });
}
});
test('sort ascending/descending, skip and limit', async () => {
const { dir, db } = await seed();
try {
assert.deepEqual(db.query({ sort: { age: 1 } }).map((r) => r.key), ['b', 'c', 'a', 'd']);
assert.deepEqual(db.query({ sort: { age: -1 } }).map((r) => r.key), ['d', 'a', 'c', 'b']);
assert.deepEqual(db.query({ sort: { age: 1 }, skip: 1, limit: 2 }).map((r) => r.key), ['c', 'a']);
// No filter / sort returns every document.
assert.equal(db.query().length, 4);
await db.close();
} finally {
await fs.rm(dir, { recursive: true, force: true });
}
});