Skip to content

Commit d5eded6

Browse files
committed
- Added resolve() import and p() helper to operations.test.ts
- Wrapped all seeded linked_files paths and path assertions with p() so they resolve correctly on Windows (/tmp/test/foo.ts → D:\tmp\test\foo.ts)
1 parent fb0506c commit d5eded6

1 file changed

Lines changed: 29 additions & 26 deletions

File tree

tests/operations.test.ts

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import { vi, describe, it, expect, beforeEach, afterEach } from 'vitest';
22
import { mkdtempSync, rmSync, mkdirSync } from 'fs';
33
import { tmpdir } from 'os';
4-
import { join } from 'path';
4+
import { join, resolve } from 'path';
5+
6+
/** Resolve a path for cross-platform compatibility (Windows resolves /tmp to D:\tmp) */
7+
const p = (filePath: string) => resolve(filePath);
58

69
// ─── Shared test infrastructure ─────────────────────────────────────────────
710

@@ -304,7 +307,7 @@ describe('attachFile', () => {
304307
attachFile({ threadId: 'store-path', filePath: '/tmp/test/component.ts' });
305308
const index = loadIndex();
306309

307-
expect(index['store-path'].linked_files).toContain('/tmp/test/component.ts');
310+
expect(index['store-path'].linked_files).toContain(p('/tmp/test/component.ts'));
308311
});
309312

310313
it('returns the filePath in data', async () => {
@@ -313,7 +316,7 @@ describe('attachFile', () => {
313316

314317
const result = attachFile({ threadId: 'data-path', filePath: '/tmp/test/api.ts' });
315318

316-
expect(result.data?.filePath).toBe('/tmp/test/api.ts');
319+
expect(result.data?.filePath).toBe(p('/tmp/test/api.ts'));
317320
});
318321

319322
it('returns success:false with THREAD_NOT_FOUND when thread does not exist', async () => {
@@ -335,7 +338,7 @@ describe('attachFile', () => {
335338

336339
it('is idempotent: returns success when file is already linked', async () => {
337340
await seedIndex({
338-
'idempotent-thread': makeThread({ linked_files: ['/tmp/test/already.ts'] }),
341+
'idempotent-thread': makeThread({ linked_files: [p('/tmp/test/already.ts')] }),
339342
});
340343
const { attachFile } = await import('../src/core/operations/attach.js');
341344

@@ -346,7 +349,7 @@ describe('attachFile', () => {
346349

347350
it('returns alreadyLinked:true when file is already linked', async () => {
348351
await seedIndex({
349-
'already-linked': makeThread({ linked_files: ['/tmp/test/linked.ts'] }),
352+
'already-linked': makeThread({ linked_files: [p('/tmp/test/linked.ts')] }),
350353
});
351354
const { attachFile } = await import('../src/core/operations/attach.js');
352355

@@ -357,14 +360,14 @@ describe('attachFile', () => {
357360

358361
it('does not duplicate a file that is already linked', async () => {
359362
await seedIndex({
360-
'no-dup': makeThread({ linked_files: ['/tmp/test/once.ts'] }),
363+
'no-dup': makeThread({ linked_files: [p('/tmp/test/once.ts')] }),
361364
});
362365
const { attachFile } = await import('../src/core/operations/attach.js');
363366
const { loadIndex } = await import('../src/core/storage.js');
364367

365368
attachFile({ threadId: 'no-dup', filePath: '/tmp/test/once.ts' });
366369
const index = loadIndex();
367-
const occurrences = index['no-dup'].linked_files.filter((f) => f === '/tmp/test/once.ts');
370+
const occurrences = index['no-dup'].linked_files.filter((f) => f === p('/tmp/test/once.ts'));
368371

369372
expect(occurrences).toHaveLength(1);
370373
});
@@ -376,15 +379,15 @@ describe('attachFile', () => {
376379
const now = new Date().toISOString();
377380
savePending({
378381
tracked: [
379-
{ path: '/tmp/test/tracked.ts', first_seen: now, last_modified: now, count: 1 },
382+
{ path: p('/tmp/test/tracked.ts'), first_seen: now, last_modified: now, count: 1 },
380383
],
381384
});
382385

383386
const { attachFile } = await import('../src/core/operations/attach.js');
384387
attachFile({ threadId: 'pending-thread', filePath: '/tmp/test/tracked.ts' });
385388

386389
const pending = loadPending();
387-
const stillTracked = pending.tracked.some((f) => f.path === '/tmp/test/tracked.ts');
390+
const stillTracked = pending.tracked.some((f) => f.path === p('/tmp/test/tracked.ts'));
388391
expect(stillTracked).toBe(false);
389392
});
390393

@@ -404,7 +407,7 @@ describe('attachFile', () => {
404407
describe('detachFile', () => {
405408
it('successfully detaches a linked file', async () => {
406409
await seedIndex({
407-
'detach-thread': makeThread({ linked_files: ['/tmp/test/remove-me.ts'] }),
410+
'detach-thread': makeThread({ linked_files: [p('/tmp/test/remove-me.ts')] }),
408411
});
409412
const { detachFile } = await import('../src/core/operations/attach.js');
410413

@@ -415,15 +418,15 @@ describe('detachFile', () => {
415418

416419
it('removes the file from linked_files in storage', async () => {
417420
await seedIndex({
418-
'storage-detach': makeThread({ linked_files: ['/tmp/test/gone.ts'] }),
421+
'storage-detach': makeThread({ linked_files: [p('/tmp/test/gone.ts')] }),
419422
});
420423
const { detachFile } = await import('../src/core/operations/attach.js');
421424
const { loadIndex } = await import('../src/core/storage.js');
422425

423426
detachFile({ threadId: 'storage-detach', filePath: '/tmp/test/gone.ts' });
424427
const index = loadIndex();
425428

426-
expect(index['storage-detach'].linked_files).not.toContain('/tmp/test/gone.ts');
429+
expect(index['storage-detach'].linked_files).not.toContain(p('/tmp/test/gone.ts'));
427430
});
428431

429432
it('returns success:false with THREAD_NOT_FOUND when thread does not exist', async () => {
@@ -451,21 +454,21 @@ describe('detachFile', () => {
451454

452455
const result = detachFile({ threadId: 'msg-thread', filePath: '/tmp/test/stranger.ts' });
453456

454-
expect(result.message).toContain('/tmp/test/stranger.ts');
457+
expect(result.message).toContain(p('/tmp/test/stranger.ts'));
455458
});
456459

457460
it('leaves other linked files untouched when detaching one', async () => {
458461
await seedIndex({
459-
'multi-file': makeThread({ linked_files: ['/tmp/test/keep.ts', '/tmp/test/remove.ts'] }),
462+
'multi-file': makeThread({ linked_files: [p('/tmp/test/keep.ts'), p('/tmp/test/remove.ts')] }),
460463
});
461464
const { detachFile } = await import('../src/core/operations/attach.js');
462465
const { loadIndex } = await import('../src/core/storage.js');
463466

464467
detachFile({ threadId: 'multi-file', filePath: '/tmp/test/remove.ts' });
465468
const index = loadIndex();
466469

467-
expect(index['multi-file'].linked_files).toContain('/tmp/test/keep.ts');
468-
expect(index['multi-file'].linked_files).not.toContain('/tmp/test/remove.ts');
470+
expect(index['multi-file'].linked_files).toContain(p('/tmp/test/keep.ts'));
471+
expect(index['multi-file'].linked_files).not.toContain(p('/tmp/test/remove.ts'));
469472
});
470473
});
471474

@@ -498,7 +501,7 @@ describe('explainFile', () => {
498501

499502
it('returns the single thread linked to a file', async () => {
500503
await seedIndex({
501-
'explain-owner': makeThread({ linked_files: ['/tmp/test/owned.ts'] }),
504+
'explain-owner': makeThread({ linked_files: [p('/tmp/test/owned.ts')] }),
502505
});
503506
const { explainFile } = await import('../src/core/operations/explain.js');
504507

@@ -510,8 +513,8 @@ describe('explainFile', () => {
510513

511514
it('returns all threads when multiple threads link to the same file', async () => {
512515
await seedIndex({
513-
'thread-a': makeThread({ linked_files: ['/tmp/test/shared.ts'] }),
514-
'thread-b': makeThread({ linked_files: ['/tmp/test/shared.ts'] }),
516+
'thread-a': makeThread({ linked_files: [p('/tmp/test/shared.ts')] }),
517+
'thread-b': makeThread({ linked_files: [p('/tmp/test/shared.ts')] }),
515518
});
516519
const { explainFile } = await import('../src/core/operations/explain.js');
517520

@@ -522,8 +525,8 @@ describe('explainFile', () => {
522525

523526
it('includes correct thread ids when multiple threads link to the same file', async () => {
524527
await seedIndex({
525-
'alpha': makeThread({ linked_files: ['/tmp/test/multi-owned.ts'] }),
526-
'beta': makeThread({ linked_files: ['/tmp/test/multi-owned.ts'] }),
528+
'alpha': makeThread({ linked_files: [p('/tmp/test/multi-owned.ts')] }),
529+
'beta': makeThread({ linked_files: [p('/tmp/test/multi-owned.ts')] }),
527530
});
528531
const { explainFile } = await import('../src/core/operations/explain.js');
529532

@@ -535,7 +538,7 @@ describe('explainFile', () => {
535538

536539
it('includes thread summary in the result', async () => {
537540
await seedIndex({
538-
'summary-thread': makeThread({ summary: 'Authentication system', linked_files: ['/tmp/test/auth.ts'] }),
541+
'summary-thread': makeThread({ summary: 'Authentication system', linked_files: [p('/tmp/test/auth.ts')] }),
539542
});
540543
const { explainFile } = await import('../src/core/operations/explain.js');
541544

@@ -547,7 +550,7 @@ describe('explainFile', () => {
547550
it('includes the snippets belonging to the matched thread', async () => {
548551
const snippet = { content: 'Used JWT for stateless auth', source: 'manual', timestamp: new Date().toISOString() };
549552
await seedIndex({
550-
'snippet-explain': makeThread({ snippets: [snippet], linked_files: ['/tmp/test/jwt.ts'] }),
553+
'snippet-explain': makeThread({ snippets: [snippet], linked_files: [p('/tmp/test/jwt.ts')] }),
551554
});
552555
const { explainFile } = await import('../src/core/operations/explain.js');
553556

@@ -562,7 +565,7 @@ describe('explainFile', () => {
562565

563566
const result = explainFile('/tmp/test/check-path.ts');
564567

565-
expect(result.data?.filePath).toBe('/tmp/test/check-path.ts');
568+
expect(result.data?.filePath).toBe(p('/tmp/test/check-path.ts'));
566569
});
567570
});
568571

@@ -666,13 +669,13 @@ describe('showThread', () => {
666669

667670
it('returns linked_files in the thread data', async () => {
668671
await seedIndex({
669-
'files-show': makeThread({ linked_files: ['/tmp/test/app.ts', '/tmp/test/db.ts'] }),
672+
'files-show': makeThread({ linked_files: [p('/tmp/test/app.ts'), p('/tmp/test/db.ts')] }),
670673
});
671674
const { showThread } = await import('../src/core/operations/show.js');
672675

673676
const result = showThread('files-show');
674677

675-
expect(result.data?.thread.linked_files).toEqual(['/tmp/test/app.ts', '/tmp/test/db.ts']);
678+
expect(result.data?.thread.linked_files).toEqual([p('/tmp/test/app.ts'), p('/tmp/test/db.ts')]);
676679
});
677680
});
678681

0 commit comments

Comments
 (0)