122 lines
3.7 KiB
TypeScript
122 lines
3.7 KiB
TypeScript
import { sql } from 'kysely';
|
|
import { afterEach, describe, expect, it } from 'vitest';
|
|
|
|
import { createDatabase } from '../src/adapters/dialect';
|
|
import { initializeSchema } from '../src/core/migrations';
|
|
|
|
const openConnections: Array<() => Promise<void>> = [];
|
|
|
|
afterEach(async () => {
|
|
while (openConnections.length > 0) {
|
|
const close = openConnections.pop();
|
|
if (close) {
|
|
await close();
|
|
}
|
|
}
|
|
});
|
|
|
|
describe('initializeSchema', () => {
|
|
it('creates the topics, facts, fact_embeddings, fact_topics, topic_relations, and topic_aliases tables', async () => {
|
|
const connection = await createDatabase({ client: 'sqlite', filename: ':memory:' });
|
|
openConnections.push(connection.destroy);
|
|
|
|
await initializeSchema(connection.db);
|
|
|
|
const tables = await sql<{ name: string }>`
|
|
SELECT name
|
|
FROM sqlite_master
|
|
WHERE type = 'table'
|
|
ORDER BY name
|
|
`.execute(connection.db);
|
|
|
|
const tableNames = tables.rows.map((row) => row.name);
|
|
|
|
expect(tableNames).toContain('topics');
|
|
expect(tableNames).toContain('facts');
|
|
expect(tableNames).toContain('fact_embeddings');
|
|
expect(tableNames).toContain('fact_topics');
|
|
expect(tableNames).toContain('topic_relations');
|
|
expect(tableNames).toContain('topic_aliases');
|
|
});
|
|
|
|
it('creates the expected columns for each table', async () => {
|
|
const connection = await createDatabase({ client: 'sqlite', filename: ':memory:' });
|
|
openConnections.push(connection.destroy);
|
|
|
|
await initializeSchema(connection.db);
|
|
|
|
const topicsColumns = await sql<{ name: string }>`PRAGMA table_info(topics)`.execute(connection.db);
|
|
const factsColumns = await sql<{ name: string }>`PRAGMA table_info(facts)`.execute(connection.db);
|
|
const factEmbeddingsColumns = await sql<{ name: string }>`PRAGMA table_info(fact_embeddings)`.execute(connection.db);
|
|
const factTopicsColumns = await sql<{ name: string }>`PRAGMA table_info(fact_topics)`.execute(connection.db);
|
|
const topicRelationsColumns = await sql<{ name: string }>`PRAGMA table_info(topic_relations)`.execute(connection.db);
|
|
const topicAliasesColumns = await sql<{ name: string }>`PRAGMA table_info(topic_aliases)`.execute(connection.db);
|
|
|
|
expect(topicsColumns.rows.map((row) => row.name)).toEqual([
|
|
'id',
|
|
'name',
|
|
'normalized_name',
|
|
'category',
|
|
'granularity',
|
|
'description',
|
|
'metadata',
|
|
'created_at',
|
|
'updated_at',
|
|
]);
|
|
|
|
expect(factsColumns.rows.map((row) => row.name)).toEqual([
|
|
'id',
|
|
'statement',
|
|
'summary',
|
|
'source',
|
|
'confidence',
|
|
'metadata',
|
|
'created_at',
|
|
'updated_at',
|
|
]);
|
|
|
|
expect(factEmbeddingsColumns.rows.map((row) => row.name)).toEqual([
|
|
'fact_id',
|
|
'model',
|
|
'dimensions',
|
|
'embedding',
|
|
'content_hash',
|
|
'created_at',
|
|
'updated_at',
|
|
]);
|
|
|
|
expect(factTopicsColumns.rows.map((row) => row.name)).toEqual([
|
|
'fact_id',
|
|
'topic_id',
|
|
'role',
|
|
'position',
|
|
'created_at',
|
|
]);
|
|
|
|
expect(topicRelationsColumns.rows.map((row) => row.name)).toEqual([
|
|
'parent_topic_id',
|
|
'child_topic_id',
|
|
'relation',
|
|
'created_at',
|
|
]);
|
|
|
|
expect(topicAliasesColumns.rows.map((row) => row.name)).toEqual([
|
|
'id',
|
|
'topic_id',
|
|
'alias',
|
|
'normalized_alias',
|
|
'is_primary',
|
|
'created_at',
|
|
'updated_at',
|
|
]);
|
|
});
|
|
|
|
it('is idempotent when called more than once', async () => {
|
|
const connection = await createDatabase({ client: 'sqlite', filename: ':memory:' });
|
|
openConnections.push(connection.destroy);
|
|
|
|
await initializeSchema(connection.db);
|
|
await expect(initializeSchema(connection.db)).resolves.toBeUndefined();
|
|
});
|
|
});
|