Skip to content

Commit 6395ce0

Browse files
author
StackMemory Bot (CLI)
committed
fix(test): replace bun:test import with vitest in desire-path-service test
1 parent 65421a8 commit 6395ce0

1 file changed

Lines changed: 114 additions & 31 deletions

File tree

src/daemon/services/__tests__/desire-path-service.test.ts

Lines changed: 114 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,18 @@
1-
import { describe, it, expect, beforeEach, afterEach } from 'bun:test';
2-
import { mkdtempSync, rmSync, writeFileSync, readFileSync, existsSync, mkdirSync } from 'fs';
1+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2+
import {
3+
mkdtempSync,
4+
rmSync,
5+
writeFileSync,
6+
readFileSync,
7+
existsSync,
8+
mkdirSync,
9+
} from 'fs';
310
import { join } from 'path';
411
import { tmpdir, homedir } from 'os';
5-
import { DaemonDesirePathService, type DesirePathConfig } from '../desire-path-service.js';
12+
import {
13+
DaemonDesirePathService,
14+
type DesirePathConfig,
15+
} from '../desire-path-service.js';
616

717
// Override SM_DIR for tests by using the service's logAction method
818
// which writes to ~/.stackmemory/desire-paths/ — we test the public API
@@ -35,7 +45,9 @@ describe('DaemonDesirePathService', () => {
3545
describe('parseHookEvent', () => {
3646
it('sanitizes file paths into glob patterns', () => {
3747
const entry = DaemonDesirePathService.parseHookEvent(
38-
'Read', '/src/runtime/agent-runner.js', 'sess-1'
48+
'Read',
49+
'/src/runtime/agent-runner.js',
50+
'sess-1'
3951
);
4052
expect(entry.tool).toBe('Read');
4153
expect(entry.target).toBe('/src/runtime/*.js');
@@ -44,20 +56,30 @@ describe('DaemonDesirePathService', () => {
4456

4557
it('sanitizes bash commands to command + first arg', () => {
4658
const entry = DaemonDesirePathService.parseHookEvent(
47-
'Bash', 'npx jest src/runtime --no-coverage', 'sess-1'
59+
'Bash',
60+
'npx jest src/runtime --no-coverage',
61+
'sess-1'
4862
);
4963
expect(entry.tool).toBe('Bash');
5064
expect(entry.target).toBe('npx jest');
5165
});
5266

5367
it('handles empty args', () => {
54-
const entry = DaemonDesirePathService.parseHookEvent('Grep', '', 'sess-1');
68+
const entry = DaemonDesirePathService.parseHookEvent(
69+
'Grep',
70+
'',
71+
'sess-1'
72+
);
5573
expect(entry.target).toBe('*');
5674
});
5775

5876
it('truncates long args', () => {
5977
const longArg = 'a'.repeat(100);
60-
const entry = DaemonDesirePathService.parseHookEvent('Glob', longArg, 'sess-1');
78+
const entry = DaemonDesirePathService.parseHookEvent(
79+
'Glob',
80+
longArg,
81+
'sess-1'
82+
);
6183
expect(entry.target.length).toBeLessThanOrEqual(50);
6284
});
6385
});
@@ -73,26 +95,74 @@ describe('DaemonDesirePathService', () => {
7395

7496
// Session 1: Read → Edit → Bash
7597
const actions = [
76-
{ ts: '2026-05-09T10:00:00Z', sid: 'sess-1', tool: 'Read', target: 'src/runtime/*.js' },
77-
{ ts: '2026-05-09T10:00:01Z', sid: 'sess-1', tool: 'Edit', target: 'src/runtime/*.js' },
78-
{ ts: '2026-05-09T10:00:02Z', sid: 'sess-1', tool: 'Bash', target: 'npx jest' },
98+
{
99+
ts: '2026-05-09T10:00:00Z',
100+
sid: 'sess-1',
101+
tool: 'Read',
102+
target: 'src/runtime/*.js',
103+
},
104+
{
105+
ts: '2026-05-09T10:00:01Z',
106+
sid: 'sess-1',
107+
tool: 'Edit',
108+
target: 'src/runtime/*.js',
109+
},
110+
{
111+
ts: '2026-05-09T10:00:02Z',
112+
sid: 'sess-1',
113+
tool: 'Bash',
114+
target: 'npx jest',
115+
},
79116
// Session 2: same pattern
80-
{ ts: '2026-05-09T11:00:00Z', sid: 'sess-2', tool: 'Read', target: 'src/runtime/*.js' },
81-
{ ts: '2026-05-09T11:00:01Z', sid: 'sess-2', tool: 'Edit', target: 'src/runtime/*.js' },
82-
{ ts: '2026-05-09T11:00:02Z', sid: 'sess-2', tool: 'Bash', target: 'npx jest' },
117+
{
118+
ts: '2026-05-09T11:00:00Z',
119+
sid: 'sess-2',
120+
tool: 'Read',
121+
target: 'src/runtime/*.js',
122+
},
123+
{
124+
ts: '2026-05-09T11:00:01Z',
125+
sid: 'sess-2',
126+
tool: 'Edit',
127+
target: 'src/runtime/*.js',
128+
},
129+
{
130+
ts: '2026-05-09T11:00:02Z',
131+
sid: 'sess-2',
132+
tool: 'Bash',
133+
target: 'npx jest',
134+
},
83135
// Session 3: same pattern again
84-
{ ts: '2026-05-09T12:00:00Z', sid: 'sess-3', tool: 'Read', target: 'src/runtime/*.js' },
85-
{ ts: '2026-05-09T12:00:01Z', sid: 'sess-3', tool: 'Edit', target: 'src/runtime/*.js' },
86-
{ ts: '2026-05-09T12:00:02Z', sid: 'sess-3', tool: 'Bash', target: 'npx jest' },
136+
{
137+
ts: '2026-05-09T12:00:00Z',
138+
sid: 'sess-3',
139+
tool: 'Read',
140+
target: 'src/runtime/*.js',
141+
},
142+
{
143+
ts: '2026-05-09T12:00:01Z',
144+
sid: 'sess-3',
145+
tool: 'Edit',
146+
target: 'src/runtime/*.js',
147+
},
148+
{
149+
ts: '2026-05-09T12:00:02Z',
150+
sid: 'sess-3',
151+
tool: 'Bash',
152+
target: 'npx jest',
153+
},
87154
];
88155

89-
writeFileSync(streamFile, actions.map(a => JSON.stringify(a)).join('\n') + '\n');
156+
writeFileSync(
157+
streamFile,
158+
actions.map((a) => JSON.stringify(a)).join('\n') + '\n'
159+
);
90160

91161
const patterns = service.detectPatterns();
92162

93163
expect(patterns.length).toBeGreaterThan(0);
94164
// Should find the Read→Edit→Bash sequence
95-
const fullPattern = patterns.find(p => p.sequence.length === 3);
165+
const fullPattern = patterns.find((p) => p.sequence.length === 3);
96166
expect(fullPattern).toBeDefined();
97167
expect(fullPattern!.frequency).toBeGreaterThanOrEqual(3);
98168
expect(fullPattern!.sessions).toBeGreaterThanOrEqual(2);
@@ -113,16 +183,22 @@ describe('DaemonDesirePathService', () => {
113183
it('generates skill markdown from patterns', () => {
114184
const service = new DaemonDesirePathService(config, onLog);
115185

116-
const patterns = [{
117-
id: 'test-1',
118-
sequence: ['Read:src/runtime/*.js', 'Edit:src/runtime/*.js', 'Bash:npx jest'],
119-
frequency: 5,
120-
sessions: 3,
121-
avg_steps: 3,
122-
first_seen: '2026-05-09T10:00:00Z',
123-
last_seen: '2026-05-09T12:00:00Z',
124-
score: 15,
125-
}];
186+
const patterns = [
187+
{
188+
id: 'test-1',
189+
sequence: [
190+
'Read:src/runtime/*.js',
191+
'Edit:src/runtime/*.js',
192+
'Bash:npx jest',
193+
],
194+
frequency: 5,
195+
sessions: 3,
196+
avg_steps: 3,
197+
first_seen: '2026-05-09T10:00:00Z',
198+
last_seen: '2026-05-09T12:00:00Z',
199+
score: 15,
200+
},
201+
];
126202

127203
const suggestions = service.generateSuggestions(patterns);
128204

@@ -133,8 +209,15 @@ describe('DaemonDesirePathService', () => {
133209
expect(suggestions[0].pattern_id).toBe('test-1');
134210

135211
// Check suggestion file was written
136-
const suggestionsDir = join(homedir(), '.stackmemory', 'desire-paths', 'suggestions');
137-
const files = require('fs').readdirSync(suggestionsDir).filter((f: string) => f.endsWith('.skill.md'));
212+
const suggestionsDir = join(
213+
homedir(),
214+
'.stackmemory',
215+
'desire-paths',
216+
'suggestions'
217+
);
218+
const files = require('fs')
219+
.readdirSync(suggestionsDir)
220+
.filter((f: string) => f.endsWith('.skill.md'));
138221
expect(files.length).toBeGreaterThan(0);
139222

140223
// Read and verify markdown structure
@@ -169,7 +252,7 @@ describe('DaemonDesirePathService', () => {
169252
const disabledConfig = { ...config, enabled: false };
170253
const service = new DaemonDesirePathService(disabledConfig, onLog);
171254
service.start();
172-
expect(logs.some(l => l.msg.includes('disabled'))).toBe(true);
255+
expect(logs.some((l) => l.msg.includes('disabled'))).toBe(true);
173256
});
174257
});
175258

0 commit comments

Comments
 (0)