mirror of
https://github.com/amitwh/markdown-converter.git
synced 2026-10-02 01:29:32 +05:30
12 commits on master since v4.7.1 baseline, taking tests 524 → 914 across 27 new suites. This commit: - Bumps package.json + README version to v4.8.0 (additive features → semver minor) - Applies Prettier formatting to all files touched during the overnight session so release build is reproducible from a clean repo New in v4.8.0: - PDF encryption close-out (D1) - KaTeX rendering test coverage - Autosave buffer + crash recovery banner - Daily notes + workspace search + doc-aware Q&A - Search sidebar panel + Ask mode - Status bar: word count, reading time, Flesch-Kincaid grade - Footnote hover preview - Smart paste (URL → link, CSV/TSV → table) - Daily notes menu item + sidebar panel + Q&A deep-link - Daily templates gallery - Pluggable DocQA engine (TF-idF default + lazy neural embeddings) Amit Haridas
89 lines
3.4 KiB
JavaScript
89 lines
3.4 KiB
JavaScript
/**
|
|
* @jest-environment node
|
|
*
|
|
* SemanticEngine tests — verify the engine interface contract and the
|
|
* fallback path. The neural engine itself isn't loaded in tests (no
|
|
* @xenova/transformers dep installed in CI); we just verify the
|
|
* graceful fallback behavior.
|
|
*/
|
|
const SemanticEngine = require('../../src/main/SemanticEngine');
|
|
const WorkspaceSearch = require('../../src/main/WorkspaceSearch');
|
|
|
|
describe('SemanticEngine.defaultEngine', () => {
|
|
test('returns an engine object with the right shape', () => {
|
|
const e = SemanticEngine.defaultEngine();
|
|
expect(e.name).toBe('tf-idf');
|
|
expect(e.isNeural).toBe(false);
|
|
expect(typeof e.rank).toBe('function');
|
|
});
|
|
|
|
test('rank() returns WorkspaceSearch-style results', async () => {
|
|
const e = SemanticEngine.defaultEngine();
|
|
const chunks = [
|
|
{ path: 'a.md', content: 'rust async with tokio', mtimeMs: 1 },
|
|
{ path: 'b.md', content: 'unrelated content', mtimeMs: 1 },
|
|
];
|
|
const r = await e.rank('rust async', chunks);
|
|
expect(r.length).toBeGreaterThan(0);
|
|
// First result should match the query
|
|
expect(r[0].filePath).toBe('a.md');
|
|
// Shape matches WorkspaceSearch
|
|
for (const hit of r) {
|
|
expect(hit).toHaveProperty('filePath');
|
|
expect(hit).toHaveProperty('score');
|
|
expect(hit).toHaveProperty('snippet');
|
|
}
|
|
});
|
|
|
|
test('rank() filters out non-matching chunks', async () => {
|
|
const e = SemanticEngine.defaultEngine();
|
|
const r = await e.rank('rust', [
|
|
{ path: 'x.md', content: 'totally unrelated prose about cats' },
|
|
{ path: 'y.md', content: 'rust rust rust everywhere' },
|
|
]);
|
|
expect(r.every((hit) => hit.filePath === 'y.md')).toBe(true);
|
|
});
|
|
});
|
|
|
|
describe('SemanticEngine.getEngine', () => {
|
|
test('returns the default engine for "tf-idf"', async () => {
|
|
const e = await SemanticEngine.getEngine('tf-idf');
|
|
expect(e.isNeural).toBe(false);
|
|
});
|
|
|
|
test('returns the default engine for an unknown name (graceful fallback)', async () => {
|
|
const e = await SemanticEngine.getEngine('not-a-real-engine');
|
|
expect(e.isNeural).toBe(false);
|
|
expect(e.name).toBe('tf-idf');
|
|
});
|
|
|
|
test('neural engine falls back to tf-idf when @xenova/transformers is missing', async () => {
|
|
// No install of @xenova/transformers in CI; the require() inside
|
|
// neuralEngine() should fail and fall back.
|
|
const e = await SemanticEngine.getEngine('transformers', { allowRemote: false });
|
|
expect(e.isNeural).toBe(false);
|
|
expect(e.name).toBe('tf-idf');
|
|
});
|
|
|
|
test('default engine is consistent across calls', () => {
|
|
const a = SemanticEngine.defaultEngine();
|
|
const b = SemanticEngine.defaultEngine();
|
|
expect(a).not.toBe(b);
|
|
expect(a.name).toBe(b.name);
|
|
});
|
|
});
|
|
|
|
describe('SemanticEngine — WorkspaceSearch parity', () => {
|
|
test('default engine returns the same shape WorkspaceSearch.search would', async () => {
|
|
const files = [
|
|
{ path: '/a.md', content: 'rust async programming', mtimeMs: 1 },
|
|
{ path: '/b.md', content: 'python web dev', mtimeMs: 2 },
|
|
];
|
|
const e = SemanticEngine.defaultEngine();
|
|
const engineResult = await e.rank('rust', files);
|
|
const directResult = WorkspaceSearch.search({ query: 'rust', files, limit: files.length });
|
|
expect(engineResult.map((r) => r.filePath)).toEqual(directResult.map((r) => r.filePath));
|
|
expect(engineResult[0].score).toBe(directResult[0].score);
|
|
});
|
|
});
|