@afterxleep/doc-bot 1.17.0 → 1.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +7 -4
- package/src/__tests__/temp-docs-1756129972061/test.md +5 -0
- package/src/__tests__/temp-docs-1756129972071/test.md +5 -0
- package/src/__tests__/temp-docs-1756129972075/test.md +5 -0
- package/src/__tests__/temp-docs-1756129972077/test.md +5 -0
- package/src/__tests__/temp-docs-1756129972079/test.md +5 -0
- package/src/__tests__/temp-docs-1756130189361/test.md +5 -0
- package/src/__tests__/temp-docs-1756130189372/test.md +5 -0
- package/src/__tests__/temp-docs-1756130189375/test.md +5 -0
- package/src/__tests__/temp-docs-1756130189378/test.md +5 -0
- package/src/__tests__/temp-docs-1756130189379/test.md +5 -0
- package/src/__tests__/temp-docs-1756130271128/test.md +5 -0
- package/src/__tests__/temp-docs-1756130271139/test.md +5 -0
- package/src/__tests__/temp-docs-1756130271142/test.md +5 -0
- package/src/__tests__/temp-docs-1756130271145/test.md +5 -0
- package/src/__tests__/temp-docs-1756130271146/test.md +5 -0
- package/src/__tests__/temp-docs-1756130687030/test.md +5 -0
- package/src/__tests__/temp-docs-1756130687044/test.md +5 -0
- package/src/__tests__/temp-docs-1756130687048/test.md +5 -0
- package/src/__tests__/temp-docs-1756130687051/test.md +5 -0
- package/src/__tests__/temp-docs-1756130687053/test.md +5 -0
- package/src/__tests__/temp-docs-1756131694925/test.md +5 -0
- package/src/__tests__/temp-docs-1756131694937/test.md +5 -0
- package/src/__tests__/temp-docs-1756131694941/test.md +5 -0
- package/src/__tests__/temp-docs-1756131694944/test.md +5 -0
- package/src/__tests__/temp-docs-1756131694946/test.md +5 -0
- package/src/__tests__/temp-docs-1756133998710/test.md +5 -0
- package/src/__tests__/temp-docs-1756133998721/test.md +5 -0
- package/src/__tests__/temp-docs-1756133998724/test.md +5 -0
- package/src/__tests__/temp-docs-1756133998727/test.md +5 -0
- package/src/__tests__/temp-docs-1756133998729/test.md +5 -0
- package/src/__tests__/temp-docs-1756134345935/test.md +5 -0
- package/src/__tests__/temp-docs-1756134345948/test.md +5 -0
- package/src/__tests__/temp-docs-1756134345952/test.md +5 -0
- package/src/__tests__/temp-docs-1756134345954/test.md +5 -0
- package/src/__tests__/temp-docs-1756134345957/test.md +5 -0
- package/src/__tests__/temp-docsets-1756129972079/2e443167/Mock.docset/Contents/Info.plist +10 -0
- package/src/__tests__/temp-docsets-1756129972079/2e443167/Mock.docset/Contents/Resources/docSet.dsidx +0 -0
- package/src/__tests__/temp-docsets-1756129972079/Mock.docset/Contents/Info.plist +10 -0
- package/src/__tests__/temp-docsets-1756129972079/Mock.docset/Contents/Resources/docSet.dsidx +0 -0
- package/src/__tests__/temp-docsets-1756129972079/docsets.json +10 -0
- package/src/__tests__/temp-docsets-1756130189379/Mock.docset/Contents/Info.plist +10 -0
- package/src/__tests__/temp-docsets-1756130189379/Mock.docset/Contents/Resources/docSet.dsidx +0 -0
- package/src/__tests__/temp-docsets-1756130189379/a4934c14/Mock.docset/Contents/Info.plist +10 -0
- package/src/__tests__/temp-docsets-1756130189379/a4934c14/Mock.docset/Contents/Resources/docSet.dsidx +0 -0
- package/src/__tests__/temp-docsets-1756130189379/docsets.json +10 -0
- package/src/__tests__/temp-docsets-1756130271146/3f8acbb2/Mock.docset/Contents/Info.plist +10 -0
- package/src/__tests__/temp-docsets-1756130271146/3f8acbb2/Mock.docset/Contents/Resources/docSet.dsidx +0 -0
- package/src/__tests__/temp-docsets-1756130271146/Mock.docset/Contents/Info.plist +10 -0
- package/src/__tests__/temp-docsets-1756130271146/Mock.docset/Contents/Resources/docSet.dsidx +0 -0
- package/src/__tests__/temp-docsets-1756130271146/docsets.json +10 -0
- package/src/__tests__/temp-docsets-1756130687053/6810e6bd/Mock.docset/Contents/Info.plist +10 -0
- package/src/__tests__/temp-docsets-1756130687053/6810e6bd/Mock.docset/Contents/Resources/docSet.dsidx +0 -0
- package/src/__tests__/temp-docsets-1756130687053/Mock.docset/Contents/Info.plist +10 -0
- package/src/__tests__/temp-docsets-1756130687053/Mock.docset/Contents/Resources/docSet.dsidx +0 -0
- package/src/__tests__/temp-docsets-1756130687053/docsets.json +10 -0
- package/src/__tests__/temp-docsets-1756131694946/Mock.docset/Contents/Info.plist +10 -0
- package/src/__tests__/temp-docsets-1756131694946/Mock.docset/Contents/Resources/docSet.dsidx +0 -0
- package/src/__tests__/temp-docsets-1756131694946/dd703046/Mock.docset/Contents/Info.plist +10 -0
- package/src/__tests__/temp-docsets-1756131694946/dd703046/Mock.docset/Contents/Resources/docSet.dsidx +0 -0
- package/src/__tests__/temp-docsets-1756131694946/docsets.json +10 -0
- package/src/__tests__/temp-docsets-1756133998729/9e061136/Mock.docset/Contents/Info.plist +10 -0
- package/src/__tests__/temp-docsets-1756133998729/9e061136/Mock.docset/Contents/Resources/docSet.dsidx +0 -0
- package/src/__tests__/temp-docsets-1756133998729/Mock.docset/Contents/Info.plist +10 -0
- package/src/__tests__/temp-docsets-1756133998729/Mock.docset/Contents/Resources/docSet.dsidx +0 -0
- package/src/__tests__/temp-docsets-1756133998729/docsets.json +10 -0
- package/src/__tests__/temp-docsets-1756134345957/03e730af/Mock.docset/Contents/Info.plist +10 -0
- package/src/__tests__/temp-docsets-1756134345957/03e730af/Mock.docset/Contents/Resources/docSet.dsidx +0 -0
- package/src/__tests__/temp-docsets-1756134345957/Mock.docset/Contents/Info.plist +10 -0
- package/src/__tests__/temp-docsets-1756134345957/Mock.docset/Contents/Resources/docSet.dsidx +0 -0
- package/src/__tests__/temp-docsets-1756134345957/docsets.json +10 -0
- package/src/index.js +269 -63
- package/src/services/DocumentationService.js +26 -1
- package/src/services/PaginationService.js +378 -0
- package/src/services/__tests__/PaginationService.integration.test.js +185 -0
- package/src/services/__tests__/PaginationService.test.js +398 -0
- package/src/utils/TokenEstimator.js +134 -0
- package/prompts/file-docs.md +0 -69
- package/prompts/global-rules.md +0 -142
- package/prompts/mandatory-rules.md +0 -90
- package/prompts/search-results.md +0 -59
- package/prompts/system-prompt.md +0 -270
- package/src/__tests__/docset-integration.test.js +0 -146
- package/src/services/__tests__/DocumentationService.test.js +0 -318
- package/src/services/__tests__/UnifiedSearchService.test.js +0 -302
- package/src/services/docset/__tests__/EnhancedDocsetDatabase.test.js +0 -324
|
@@ -1,324 +0,0 @@
|
|
|
1
|
-
import { DocsetDatabase, MultiDocsetDatabase } from '../database.js';
|
|
2
|
-
import Database from 'better-sqlite3';
|
|
3
|
-
import path from 'path';
|
|
4
|
-
import fs from 'fs-extra';
|
|
5
|
-
import { fileURLToPath } from 'url';
|
|
6
|
-
import { dirname } from 'path';
|
|
7
|
-
|
|
8
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
9
|
-
const __dirname = dirname(__filename);
|
|
10
|
-
|
|
11
|
-
describe('Enhanced DocsetDatabase', () => {
|
|
12
|
-
let tempDir;
|
|
13
|
-
let docsetInfo;
|
|
14
|
-
let docsetDb;
|
|
15
|
-
let sqliteDb;
|
|
16
|
-
|
|
17
|
-
beforeEach(async () => {
|
|
18
|
-
// Create temporary docset structure
|
|
19
|
-
tempDir = path.join(__dirname, 'temp-docset-' + Date.now());
|
|
20
|
-
const resourcesPath = path.join(tempDir, 'Contents', 'Resources');
|
|
21
|
-
await fs.ensureDir(resourcesPath);
|
|
22
|
-
|
|
23
|
-
// Create SQLite database
|
|
24
|
-
const dbPath = path.join(resourcesPath, 'docSet.dsidx');
|
|
25
|
-
sqliteDb = new Database(dbPath);
|
|
26
|
-
sqliteDb.exec(`
|
|
27
|
-
CREATE TABLE searchIndex(
|
|
28
|
-
id INTEGER PRIMARY KEY,
|
|
29
|
-
name TEXT,
|
|
30
|
-
type TEXT,
|
|
31
|
-
path TEXT
|
|
32
|
-
);
|
|
33
|
-
`);
|
|
34
|
-
|
|
35
|
-
// Insert test data
|
|
36
|
-
const stmt = sqliteDb.prepare('INSERT INTO searchIndex (name, type, path) VALUES (?, ?, ?)');
|
|
37
|
-
stmt.run('AlarmKit', 'Framework', 'alarmkit.html');
|
|
38
|
-
stmt.run('AlarmKit.Alarm', 'Class', 'alarmkit/alarm.html');
|
|
39
|
-
stmt.run('AlarmKit.AlarmManager', 'Class', 'alarmkit/manager.html');
|
|
40
|
-
stmt.run('URLSession', 'Class', 'urlsession.html');
|
|
41
|
-
stmt.run('URLSession.shared', 'Property', 'urlsession/shared.html');
|
|
42
|
-
stmt.run('URLSessionConfiguration', 'Class', 'urlsessionconfig.html');
|
|
43
|
-
stmt.run('TestFramework', 'Framework', 'test.html');
|
|
44
|
-
sqliteDb.close();
|
|
45
|
-
|
|
46
|
-
docsetInfo = {
|
|
47
|
-
id: 'test-docset',
|
|
48
|
-
name: 'Test Docset',
|
|
49
|
-
path: tempDir
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
docsetDb = new DocsetDatabase(docsetInfo);
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
afterEach(async () => {
|
|
56
|
-
docsetDb.close();
|
|
57
|
-
await fs.remove(tempDir);
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
describe('searchWithTerms', () => {
|
|
61
|
-
it('should find exact phrase matches with high score', () => {
|
|
62
|
-
const results = docsetDb.searchWithTerms(['alarmkit', 'alarm'], null, 10);
|
|
63
|
-
|
|
64
|
-
const exactMatch = results.find(r => r.name === 'AlarmKit.Alarm');
|
|
65
|
-
expect(exactMatch).toBeDefined();
|
|
66
|
-
expect(exactMatch.isExactPhrase).toBe(true);
|
|
67
|
-
expect(exactMatch.relevanceScore).toBeGreaterThan(90);
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
it('should find entries containing all search terms', () => {
|
|
71
|
-
const results = docsetDb.searchWithTerms(['urlsession', 'configuration'], null, 10);
|
|
72
|
-
|
|
73
|
-
// Should find URLSessionConfiguration since it contains both terms
|
|
74
|
-
const configResult = results.find(r => r.name === 'URLSessionConfiguration');
|
|
75
|
-
expect(configResult).toBeDefined();
|
|
76
|
-
expect(configResult.matchedTerms).toBe(2);
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
it('should prioritize entries with all terms over partial matches', () => {
|
|
80
|
-
const results = docsetDb.searchWithTerms(['urlsession', 'shared'], null, 10);
|
|
81
|
-
|
|
82
|
-
// URLSession.shared should rank first as it contains both terms
|
|
83
|
-
expect(results[0].name).toBe('URLSession.shared');
|
|
84
|
-
expect(results[0].matchedTerms).toBe(2);
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
it('should handle single term searches', () => {
|
|
88
|
-
const results = docsetDb.searchWithTerms(['alarmkit'], null, 10);
|
|
89
|
-
|
|
90
|
-
expect(results.length).toBeGreaterThan(0);
|
|
91
|
-
const frameworkResult = results.find(r => r.name === 'AlarmKit' && r.type === 'Framework');
|
|
92
|
-
expect(frameworkResult).toBeDefined();
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
it('should respect type filter', () => {
|
|
96
|
-
const results = docsetDb.searchWithTerms(['alarmkit'], 'Class', 10);
|
|
97
|
-
|
|
98
|
-
expect(results.every(r => r.type === 'Class')).toBe(true);
|
|
99
|
-
expect(results.some(r => r.name.includes('AlarmKit'))).toBe(true);
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
it('should prefer shorter names for equal relevance', () => {
|
|
103
|
-
const results = docsetDb.searchWithTerms(['test'], null, 10);
|
|
104
|
-
|
|
105
|
-
if (results.length > 1 && results[0].relevanceScore === results[1].relevanceScore) {
|
|
106
|
-
expect(results[0].name.length).toBeLessThanOrEqual(results[1].name.length);
|
|
107
|
-
}
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
it('should score exact name matches highest', () => {
|
|
111
|
-
const results = docsetDb.searchWithTerms(['urlsession'], null, 10);
|
|
112
|
-
|
|
113
|
-
const exactMatch = results.find(r => r.name.toLowerCase() === 'urlsession');
|
|
114
|
-
if (exactMatch) {
|
|
115
|
-
expect(results.indexOf(exactMatch)).toBeLessThan(3); // Should be in top 3
|
|
116
|
-
}
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
it('should handle no matches gracefully', () => {
|
|
120
|
-
const results = docsetDb.searchWithTerms(['nonexistent', 'terms'], null, 10);
|
|
121
|
-
|
|
122
|
-
expect(results).toEqual([]);
|
|
123
|
-
});
|
|
124
|
-
});
|
|
125
|
-
});
|
|
126
|
-
|
|
127
|
-
describe('MultiDocsetDatabase enhanced features', () => {
|
|
128
|
-
let multiDb;
|
|
129
|
-
let tempDirs;
|
|
130
|
-
|
|
131
|
-
beforeEach(async () => {
|
|
132
|
-
multiDb = new MultiDocsetDatabase();
|
|
133
|
-
tempDirs = [];
|
|
134
|
-
|
|
135
|
-
// Create multiple mock docsets
|
|
136
|
-
for (let i = 0; i < 2; i++) {
|
|
137
|
-
const tempDir = path.join(__dirname, `temp-docset-${i}-${Date.now()}`);
|
|
138
|
-
tempDirs.push(tempDir);
|
|
139
|
-
|
|
140
|
-
const resourcesPath = path.join(tempDir, 'Contents', 'Resources');
|
|
141
|
-
await fs.ensureDir(resourcesPath);
|
|
142
|
-
|
|
143
|
-
const dbPath = path.join(resourcesPath, 'docSet.dsidx');
|
|
144
|
-
const db = new Database(dbPath);
|
|
145
|
-
db.exec(`
|
|
146
|
-
CREATE TABLE searchIndex(
|
|
147
|
-
id INTEGER PRIMARY KEY,
|
|
148
|
-
name TEXT,
|
|
149
|
-
type TEXT,
|
|
150
|
-
path TEXT
|
|
151
|
-
);
|
|
152
|
-
`);
|
|
153
|
-
|
|
154
|
-
// Insert different data in each docset
|
|
155
|
-
const stmt = db.prepare('INSERT INTO searchIndex (name, type, path) VALUES (?, ?, ?)');
|
|
156
|
-
if (i === 0) {
|
|
157
|
-
stmt.run('AlarmKit', 'Framework', 'alarmkit.html?language=swift');
|
|
158
|
-
stmt.run('AlarmKit', 'Framework', 'alarmkit.html'); // Duplicate without Swift
|
|
159
|
-
stmt.run('AlarmKit.Alarm', 'Class', 'alarm.html');
|
|
160
|
-
} else {
|
|
161
|
-
stmt.run('NotificationKit', 'Framework', 'notifkit.html');
|
|
162
|
-
stmt.run('AlarmKit.Schedule', 'Class', 'schedule.html');
|
|
163
|
-
}
|
|
164
|
-
db.close();
|
|
165
|
-
|
|
166
|
-
multiDb.addDocset({
|
|
167
|
-
id: `docset-${i}`,
|
|
168
|
-
name: `Docset ${i}`,
|
|
169
|
-
path: tempDir
|
|
170
|
-
});
|
|
171
|
-
}
|
|
172
|
-
});
|
|
173
|
-
|
|
174
|
-
afterEach(async () => {
|
|
175
|
-
multiDb.closeAll();
|
|
176
|
-
for (const dir of tempDirs) {
|
|
177
|
-
await fs.remove(dir);
|
|
178
|
-
}
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
describe('searchWithTerms across multiple docsets', () => {
|
|
182
|
-
it('should search all docsets and combine results', () => {
|
|
183
|
-
const results = multiDb.searchWithTerms(['alarmkit'], { limit: 10 });
|
|
184
|
-
|
|
185
|
-
expect(results.length).toBeGreaterThan(0);
|
|
186
|
-
// Should find entries from both docsets
|
|
187
|
-
const docsetIds = new Set(results.map(r => r.docsetId));
|
|
188
|
-
expect(docsetIds.size).toBe(2);
|
|
189
|
-
});
|
|
190
|
-
|
|
191
|
-
it('should deduplicate results preferring Swift entries', () => {
|
|
192
|
-
const results = multiDb.searchWithTerms(['alarmkit'], { limit: 10 });
|
|
193
|
-
|
|
194
|
-
// Count AlarmKit Framework entries
|
|
195
|
-
const alarmKitFrameworks = results.filter(r =>
|
|
196
|
-
r.name === 'AlarmKit' && r.type === 'Framework'
|
|
197
|
-
);
|
|
198
|
-
|
|
199
|
-
// Should only have one after deduplication
|
|
200
|
-
expect(alarmKitFrameworks.length).toBe(1);
|
|
201
|
-
// And it should be the Swift version
|
|
202
|
-
expect(alarmKitFrameworks[0].url).toContain('language=swift');
|
|
203
|
-
});
|
|
204
|
-
|
|
205
|
-
it('should respect docsetId filter', () => {
|
|
206
|
-
const results = multiDb.searchWithTerms(['alarmkit'], {
|
|
207
|
-
docsetId: 'docset-0',
|
|
208
|
-
limit: 10
|
|
209
|
-
});
|
|
210
|
-
|
|
211
|
-
expect(results.every(r => r.docsetId === 'docset-0')).toBe(true);
|
|
212
|
-
});
|
|
213
|
-
|
|
214
|
-
it('should sort by relevance score', () => {
|
|
215
|
-
const results = multiDb.searchWithTerms(['alarmkit'], { limit: 10 });
|
|
216
|
-
|
|
217
|
-
for (let i = 1; i < results.length; i++) {
|
|
218
|
-
expect(results[i].relevanceScore).toBeLessThanOrEqual(results[i-1].relevanceScore);
|
|
219
|
-
}
|
|
220
|
-
});
|
|
221
|
-
});
|
|
222
|
-
|
|
223
|
-
describe('exploreAPI', () => {
|
|
224
|
-
it('should find framework and related entries', () => {
|
|
225
|
-
const exploration = multiDb.exploreAPI('AlarmKit');
|
|
226
|
-
|
|
227
|
-
expect(exploration.framework).toBeDefined();
|
|
228
|
-
expect(exploration.framework.name).toBe('AlarmKit');
|
|
229
|
-
expect(exploration.classes.length).toBeGreaterThan(0);
|
|
230
|
-
expect(exploration.classes.some(c => c.name === 'AlarmKit.Alarm')).toBe(true);
|
|
231
|
-
});
|
|
232
|
-
|
|
233
|
-
it('should categorize entries by type', () => {
|
|
234
|
-
const exploration = multiDb.exploreAPI('AlarmKit');
|
|
235
|
-
|
|
236
|
-
// Check that entries are properly categorized
|
|
237
|
-
expect(exploration.classes.every(e => e.type === 'Class')).toBe(true);
|
|
238
|
-
expect(exploration.framework?.type).toBe('Framework');
|
|
239
|
-
});
|
|
240
|
-
|
|
241
|
-
it('should search across all docsets', () => {
|
|
242
|
-
const exploration = multiDb.exploreAPI('AlarmKit');
|
|
243
|
-
|
|
244
|
-
// Should find AlarmKit.Schedule from second docset
|
|
245
|
-
expect(exploration.classes.some(c => c.name === 'AlarmKit.Schedule')).toBe(true);
|
|
246
|
-
});
|
|
247
|
-
|
|
248
|
-
it('should respect docsetId option', () => {
|
|
249
|
-
const exploration = multiDb.exploreAPI('AlarmKit', { docsetId: 'docset-0' });
|
|
250
|
-
|
|
251
|
-
// Should not find AlarmKit.Schedule which is only in docset-1
|
|
252
|
-
expect(exploration.classes.some(c => c.name === 'AlarmKit.Schedule')).toBe(false);
|
|
253
|
-
});
|
|
254
|
-
|
|
255
|
-
it('should handle entries without exact framework match', () => {
|
|
256
|
-
const exploration = multiDb.exploreAPI('URLSession');
|
|
257
|
-
|
|
258
|
-
// Even without a Framework entry, should find related classes
|
|
259
|
-
expect(exploration.framework).toBeNull();
|
|
260
|
-
expect(exploration.classes.length).toBe(0); // No URLSession in our test data
|
|
261
|
-
});
|
|
262
|
-
|
|
263
|
-
it('should include only specified types', () => {
|
|
264
|
-
const exploration = multiDb.exploreAPI('AlarmKit', {
|
|
265
|
-
includeTypes: ['Framework', 'Class']
|
|
266
|
-
});
|
|
267
|
-
|
|
268
|
-
// Should only have frameworks and classes
|
|
269
|
-
const allEntries = [
|
|
270
|
-
exploration.framework,
|
|
271
|
-
...exploration.classes,
|
|
272
|
-
...exploration.methods,
|
|
273
|
-
...exploration.properties
|
|
274
|
-
].filter(Boolean);
|
|
275
|
-
|
|
276
|
-
expect(allEntries.every(e => ['Framework', 'Class'].includes(e.type))).toBe(true);
|
|
277
|
-
});
|
|
278
|
-
});
|
|
279
|
-
|
|
280
|
-
describe('ParallelSearchManager integration', () => {
|
|
281
|
-
beforeEach(async () => {
|
|
282
|
-
// Add more docsets to trigger parallel search
|
|
283
|
-
for (let i = 2; i < 5; i++) {
|
|
284
|
-
const tempDir = path.join(__dirname, `temp-docset-${i}-${Date.now()}`);
|
|
285
|
-
tempDirs.push(tempDir);
|
|
286
|
-
|
|
287
|
-
const resourcesPath = path.join(tempDir, 'Contents', 'Resources');
|
|
288
|
-
await fs.ensureDir(resourcesPath);
|
|
289
|
-
|
|
290
|
-
const dbPath = path.join(resourcesPath, 'docSet.dsidx');
|
|
291
|
-
const db = new Database(dbPath);
|
|
292
|
-
db.exec(`
|
|
293
|
-
CREATE TABLE searchIndex(
|
|
294
|
-
id INTEGER PRIMARY KEY,
|
|
295
|
-
name TEXT,
|
|
296
|
-
type TEXT,
|
|
297
|
-
path TEXT
|
|
298
|
-
);
|
|
299
|
-
`);
|
|
300
|
-
|
|
301
|
-
db.prepare('INSERT INTO searchIndex (name, type, path) VALUES (?, ?, ?)')
|
|
302
|
-
.run(`TestClass${i}`, 'Class', `test${i}.html`);
|
|
303
|
-
db.close();
|
|
304
|
-
|
|
305
|
-
multiDb.addDocset({
|
|
306
|
-
id: `docset-${i}`,
|
|
307
|
-
name: `Docset ${i}`,
|
|
308
|
-
path: tempDir
|
|
309
|
-
});
|
|
310
|
-
}
|
|
311
|
-
});
|
|
312
|
-
|
|
313
|
-
it('should use parallel search for multiple docsets', async () => {
|
|
314
|
-
// With 5 docsets, should trigger parallel search (threshold is >3)
|
|
315
|
-
expect(multiDb.databases.size).toBe(5);
|
|
316
|
-
|
|
317
|
-
const results = await multiDb.searchWithTerms(['test'], { limit: 20 });
|
|
318
|
-
|
|
319
|
-
// Should find results from multiple docsets
|
|
320
|
-
const docsetIds = new Set(results.map(r => r.docsetId));
|
|
321
|
-
expect(docsetIds.size).toBeGreaterThanOrEqual(3);
|
|
322
|
-
});
|
|
323
|
-
});
|
|
324
|
-
});
|