Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions src/lib/__tests__/orama-index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { describe, it, expect, beforeEach } from 'vitest';
import { addToOramaMap, clearOramaDb, oramaIdMap, createOramaIndex, oramaDb } from '../search/orama-index';

describe('Orama index utilities', () => {
beforeEach(() => {
clearOramaDb();
});

describe('addToOramaMap', () => {
it('adds entries to the map', () => {
addToOramaMap('key1', 'value1');
expect(oramaIdMap.get('key1')).toBe('value1');
});

it('overwrites existing keys', () => {
addToOramaMap('key1', 'value1');
addToOramaMap('key1', 'value2');
expect(oramaIdMap.get('key1')).toBe('value2');
});

it('evicts oldest entry when map reaches max size', () => {
// Fill to max
for (let i = 0; i < 10000; i++) {
addToOramaMap(`k${i}`, `v${i}`);
}
expect(oramaIdMap.size).toBe(10000);

// Add one more — should evict oldest
addToOramaMap('overflow', 'new');
expect(oramaIdMap.size).toBe(10000);
expect(oramaIdMap.has('overflow')).toBe(true);
});
});

describe('clearOramaDb', () => {
it('clears the id map', () => {
addToOramaMap('a', 'b');
clearOramaDb();
expect(oramaIdMap.size).toBe(0);
});

it('sets oramaDb to null', () => {
clearOramaDb();
// oramaDb should be null after clear
expect(oramaDb).toBeNull();
});
});

describe('createOramaIndex', () => {
it('creates an Orama database instance', () => {
const db = createOramaIndex();
expect(db).toBeDefined();
expect(db).not.toBeNull();
});

it('sets the module-level oramaDb', () => {
createOramaIndex();
expect(oramaDb).not.toBeNull();
});

it('creates a fresh instance each time', () => {
const db1 = createOramaIndex();
clearOramaDb();
const db2 = createOramaIndex();
// Both should be valid but different instances
expect(db1).toBeDefined();
expect(db2).toBeDefined();
});
});
});
168 changes: 168 additions & 0 deletions src/lib/__tests__/perf-core.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
import { describe, it, expect, beforeEach } from 'vitest';
import { perf } from '../perf/core';

// In vitest, import.meta.env.DEV is true and window exists (happy-dom),
// so perf.mark/perf.measure will actually execute.

describe('perf', () => {
beforeEach(() => {
perf.clear();
});

describe('mark and measure', () => {
it('mark creates a performance mark without throwing', () => {
expect(() => perf.mark('test-mark')).not.toThrow();
});

it('measure returns a duration after mark', () => {
perf.mark('start');
// Small busy-wait to ensure measurable duration
const t0 = performance.now();
while (performance.now() - t0 < 2) { /* spin */ }
const duration = perf.measure('test-measure', 'start');
expect(duration).not.toBeNull();
expect(typeof duration).toBe('number');
});

it('measure stores entries', () => {
perf.mark('a');
perf.measure('entry-a', 'a');
const entries = perf.getEntries();
expect(entries.length).toBeGreaterThanOrEqual(1);
expect(entries.some(e => e.name === 'entry-a')).toBe(true);
});
});

describe('getEntries', () => {
it('returns empty array initially', () => {
perf.clear();
expect(perf.getEntries()).toEqual([]);
});

it('returns readonly entries', () => {
perf.mark('x');
perf.measure('test', 'x');
const entries = perf.getEntries();
expect(entries.length).toBeGreaterThanOrEqual(1);
});
});

describe('getEntriesByName', () => {
it('filters entries by name', () => {
perf.mark('s1');
perf.measure('filter-test', 's1');
perf.mark('s2');
perf.measure('other', 's2');
const filtered = perf.getEntriesByName('filter-test');
expect(filtered.every(e => e.name === 'filter-test')).toBe(true);
});

it('returns empty array for unknown name', () => {
expect(perf.getEntriesByName('nonexistent')).toEqual([]);
});
});

describe('getStats', () => {
it('returns null for unknown name', () => {
expect(perf.getStats('unknown')).toBeNull();
});

it('returns stats with correct structure', () => {
perf.mark('s');
perf.measure('stats-test', 's');
const stats = perf.getStats('stats-test');
expect(stats).not.toBeNull();
expect(stats!.name).toBe('stats-test');
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Forbidden non-null assertion


Using non-null assertions cancels out the benefits of strict null-checking, and introduces the possibility of runtime errors. Avoid non-null assertions unless absolutely necessary. If you still need to use one, write a skipcq comment to explain why it is safe.

expect(stats!.count).toBe(1);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Forbidden non-null assertion


Using non-null assertions cancels out the benefits of strict null-checking, and introduces the possibility of runtime errors. Avoid non-null assertions unless absolutely necessary. If you still need to use one, write a skipcq comment to explain why it is safe.

expect(typeof stats!.avgMs).toBe('number');
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Forbidden non-null assertion


Using non-null assertions cancels out the benefits of strict null-checking, and introduces the possibility of runtime errors. Avoid non-null assertions unless absolutely necessary. If you still need to use one, write a skipcq comment to explain why it is safe.

expect(typeof stats!.minMs).toBe('number');
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Forbidden non-null assertion


Using non-null assertions cancels out the benefits of strict null-checking, and introduces the possibility of runtime errors. Avoid non-null assertions unless absolutely necessary. If you still need to use one, write a skipcq comment to explain why it is safe.

expect(typeof stats!.maxMs).toBe('number');
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Forbidden non-null assertion


Using non-null assertions cancels out the benefits of strict null-checking, and introduces the possibility of runtime errors. Avoid non-null assertions unless absolutely necessary. If you still need to use one, write a skipcq comment to explain why it is safe.

expect(typeof stats!.lastMs).toBe('number');
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Forbidden non-null assertion


Using non-null assertions cancels out the benefits of strict null-checking, and introduces the possibility of runtime errors. Avoid non-null assertions unless absolutely necessary. If you still need to use one, write a skipcq comment to explain why it is safe.

});
});

describe('getAllStats', () => {
it('returns grouped stats', () => {
perf.mark('a1');
perf.measure('group-a', 'a1');
perf.mark('a2');
perf.measure('group-a', 'a2');
perf.mark('b1');
perf.measure('group-b', 'b1');

const allStats = perf.getAllStats();
const names = allStats.map(s => s.name);
expect(names).toContain('group-a');
expect(names).toContain('group-b');

const groupA = allStats.find(s => s.name === 'group-a');
expect(groupA!.count).toBe(2);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Forbidden non-null assertion


Using non-null assertions cancels out the benefits of strict null-checking, and introduces the possibility of runtime errors. Avoid non-null assertions unless absolutely necessary. If you still need to use one, write a skipcq comment to explain why it is safe.

});

it('returns empty array when no entries', () => {
perf.clear();
expect(perf.getAllStats()).toEqual([]);
});
});

describe('getStatsByCategory', () => {
it('groups entries by category prefix', () => {
perf.mark('s1');
perf.measure('sqlite-query', 's1');
perf.mark('s2');
perf.measure('orama-search', 's2');

const byCategory = perf.getStatsByCategory();
expect(byCategory.has('SQLite')).toBe(true);
expect(byCategory.has('Orama Search')).toBe(true);
});

it('categorizes known prefixes correctly', () => {
const testCases = [
{ name: 'react:render', expected: 'React Render' },
{ name: 'sqlite-query', expected: 'SQLite' },
{ name: 'orama-search', expected: 'Orama Search' },
{ name: 'search-ui', expected: 'Search UI' },
{ name: 'app-boot', expected: 'App Boot' },
{ name: 'graph-render', expected: 'Graph Rendering' },
{ name: 'mindmap-load', expected: 'Mind Map' },
{ name: 'editor-save', expected: 'Editor' },
{ name: 'fts-index', expected: 'FTS Indexing' },
{ name: 'random-metric', expected: 'Other' },
];

for (const tc of testCases) {
perf.mark(`cat-${tc.name}`);
perf.measure(tc.name, `cat-${tc.name}`);
}

const byCategory = perf.getStatsByCategory();
for (const { name, expected } of testCases) {
const stats = byCategory.get(expected);
expect(stats, `Category '${expected}' should exist for '${name}'`).toBeDefined();
expect(stats!.some(s => s.name === name)).toBe(true);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Forbidden non-null assertion


Using non-null assertions cancels out the benefits of strict null-checking, and introduces the possibility of runtime errors. Avoid non-null assertions unless absolutely necessary. If you still need to use one, write a skipcq comment to explain why it is safe.

}
});
});

describe('clear', () => {
it('clears all entries', () => {
perf.mark('c1');
perf.measure('clear-test', 'c1');
expect(perf.getEntries().length).toBeGreaterThanOrEqual(1);
perf.clear();
expect(perf.getEntries().length).toBe(0);
});
});

describe('MAX_ENTRIES limit', () => {
it('caps entries at 500', () => {
for (let i = 0; i < 510; i++) {
perf.mark(`cap-${i}`);
perf.measure(`cap-entry-${i}`, `cap-${i}`);
}
// After 510 entries, should be capped at 500
expect(perf.getEntries().length).toBeLessThanOrEqual(500);
});
});
});
Loading