GitNexus/gitnexus/test/integration/lbug-vector-extension.test.ts
Gergő Magyar 2a0c97c178
fix: add platform-aware semantic fallback (#1150)
* fix: add platform-aware semantic fallback

Make VECTOR an optional capability so Windows analysis remains stable while semantic embeddings can fall back to exact scan when native vector indexing is unavailable.

Made-with: Cursor

* fix: remove stale vector pool import

Keep the merge with main lint-clean after VECTOR loading moved out of the read pool.
2026-04-28 12:21:25 +01:00

75 lines
2.9 KiB
TypeScript

/**
* Integration Tests: Vector extension loading and state reset
*
* Tests: loadVectorExtension idempotency, vectorExtensionLoaded reset
* on closeLbug and busy-retry cleanup paths.
*
* Follows existing lbug integration test patterns (lbug-core-adapter,
* lbug-lock-retry).
*/
import { describe, it, expect } from 'vitest';
import { withTestLbugDB } from '../helpers/test-indexed-db.js';
withTestLbugDB('vector-extension', (handle) => {
describe('loadVectorExtension', () => {
it('reports VECTOR availability without throwing', async () => {
const { loadVectorExtension } = await import('../../src/core/lbug/lbug-adapter.js');
await expect(loadVectorExtension()).resolves.toEqual(expect.any(Boolean));
});
it('is idempotent -- calling twice does not throw', async () => {
const { loadVectorExtension } = await import('../../src/core/lbug/lbug-adapter.js');
await loadVectorExtension();
await expect(loadVectorExtension()).resolves.toEqual(expect.any(Boolean));
});
});
describe('vectorExtensionLoaded reset on closeLbug', () => {
it('re-initializes vector extension after close + re-init cycle', async () => {
const adapter = await import('../../src/core/lbug/lbug-adapter.js');
// Ensure vector extension is loaded
await adapter.loadVectorExtension();
// Close the adapter -- should reset vectorExtensionLoaded
await adapter.closeLbug();
expect(adapter.isLbugReady()).toBe(false);
// Re-initialize -- VECTOR is lazy, so the stale loaded flag must not mask
// a subsequent explicit availability check.
await adapter.initLbug(handle.dbPath);
expect(adapter.isLbugReady()).toBe(true);
// loadVectorExtension should succeed (not skip due to stale flag)
await expect(adapter.loadVectorExtension()).resolves.toEqual(expect.any(Boolean));
});
});
describe('vectorExtensionLoaded reset on busy-retry cleanup', () => {
it('withLbugDb resets vectorExtensionLoaded on BUSY retry', async () => {
const adapter = await import('../../src/core/lbug/lbug-adapter.js');
// Ensure vector extension is loaded
await adapter.loadVectorExtension();
// Simulate a BUSY error on first attempt, success on second.
// The retry path should reset vectorExtensionLoaded so the
// re-initialized DB gets a fresh extension load.
let callCount = 0;
const result = await adapter.withLbugDb(handle.dbPath, async () => {
callCount++;
if (callCount === 1) throw new Error('database is BUSY');
return 'recovered';
});
expect(result).toBe('recovered');
expect(callCount).toBe(2);
// After recovery, vector extension should still be loadable
// (the flag was reset and re-loaded during re-init)
await expect(adapter.loadVectorExtension()).resolves.toEqual(expect.any(Boolean));
});
});
});