This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
/**
|
||||
* SessionStore tests — full-file port from
|
||||
* hive-mind/packages/core/src/mind/sessions.test.ts.
|
||||
*
|
||||
* Memory Sync Repair Step 2. Source: hive-mind file at HEAD c363257.
|
||||
*
|
||||
* Filename suffix `-hive-mind` keeps this distinct from waggle-os's
|
||||
* own `sessions.test.ts` (which focuses on `ensureActive` semantics
|
||||
* for the agent loop). The hive-mind file covers create/close/archive/
|
||||
* ensure/getByProject + ensureActive — broader API surface coverage.
|
||||
*
|
||||
* Adapted imports: `./db.js`, `./sessions.js` → `../../src/mind/...`.
|
||||
*/
|
||||
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
||||
import { tmpdir } from 'node:os';
|
||||
import { join } from 'node:path';
|
||||
import { rmSync, existsSync } from 'node:fs';
|
||||
import { MindDB } from '../../src/mind/db.js';
|
||||
import { SessionStore } from '../../src/mind/sessions.js';
|
||||
|
||||
describe('SessionStore (hive-mind port)', () => {
|
||||
let dbPath: string;
|
||||
let db: MindDB;
|
||||
let sessions: SessionStore;
|
||||
|
||||
beforeEach(() => {
|
||||
dbPath = join(tmpdir(), `waggle-mind-sessions-test-${Date.now()}-${Math.random()}.mind`);
|
||||
db = new MindDB(dbPath);
|
||||
sessions = new SessionStore(db);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
db.close();
|
||||
if (existsSync(dbPath)) rmSync(dbPath);
|
||||
for (const suffix of ['-shm', '-wal']) {
|
||||
if (existsSync(dbPath + suffix)) rmSync(dbPath + suffix);
|
||||
}
|
||||
});
|
||||
|
||||
it('create() produces an active session with a unique gop_id', () => {
|
||||
const a = sessions.create('project-x');
|
||||
const b = sessions.create('project-x');
|
||||
expect(a.status).toBe('active');
|
||||
expect(b.status).toBe('active');
|
||||
expect(a.gop_id).not.toBe(b.gop_id);
|
||||
expect(a.project_id).toBe('project-x');
|
||||
expect(a.ended_at).toBeNull();
|
||||
});
|
||||
|
||||
it('close() transitions status and sets ended_at + summary', () => {
|
||||
const s = sessions.create();
|
||||
const closed = sessions.close(s.gop_id, 'summary-text');
|
||||
expect(closed.status).toBe('closed');
|
||||
expect(closed.ended_at).not.toBeNull();
|
||||
expect(closed.summary).toBe('summary-text');
|
||||
});
|
||||
|
||||
it('archive() transitions status without touching ended_at', () => {
|
||||
const s = sessions.create();
|
||||
const archived = sessions.archive(s.gop_id);
|
||||
expect(archived.status).toBe('archived');
|
||||
});
|
||||
|
||||
it('ensureActive() returns the existing active session or creates a new one', () => {
|
||||
const first = sessions.ensureActive('p1');
|
||||
expect(first.status).toBe('active');
|
||||
|
||||
const second = sessions.ensureActive('p1');
|
||||
expect(second.id).toBe(first.id);
|
||||
expect(second.gop_id).toBe(first.gop_id);
|
||||
|
||||
sessions.close(first.gop_id);
|
||||
const third = sessions.ensureActive('p1');
|
||||
expect(third.id).not.toBe(first.id);
|
||||
expect(third.status).toBe('active');
|
||||
});
|
||||
|
||||
it('ensure() is idempotent for a stable gop_id', () => {
|
||||
const a = sessions.ensure('harvest', undefined, 'long-lived harvest session');
|
||||
const b = sessions.ensure('harvest');
|
||||
expect(a.id).toBe(b.id);
|
||||
expect(a.summary).toBe('long-lived harvest session');
|
||||
expect(b.summary).toBe('long-lived harvest session');
|
||||
});
|
||||
|
||||
it('getByProject() returns sessions sorted newest-first', () => {
|
||||
const a = sessions.create('proj');
|
||||
sessions.close(a.gop_id);
|
||||
const b = sessions.create('proj');
|
||||
|
||||
const list = sessions.getByProject('proj');
|
||||
expect(list).toHaveLength(2);
|
||||
expect(list[0].id).toBe(b.id);
|
||||
expect(list[1].id).toBe(a.id);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user