-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlessons.test.ts
More file actions
100 lines (86 loc) · 4.2 KB
/
Copy pathlessons.test.ts
File metadata and controls
100 lines (86 loc) · 4.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
import { LessonExtractor } from "../src/history/lesson-extractor.js";
import { EventStore } from "../src/history/event-store.js";
import * as fs from "fs";
import * as path from "path";
import * as os from "os";
describe("LessonExtractor", () => {
const testDir = path.join(os.tmpdir(), "refiner-lesson-test-" + Date.now());
beforeEach(() => {
process.env.PROMPT_REFINER_GLOBAL_DIR = testDir;
if (fs.existsSync(testDir)) {
fs.rmSync(testDir, { recursive: true, force: true });
}
(EventStore as any).instance = null;
});
afterEach(() => {
const store = EventStore.getInstance();
store.close();
if (fs.existsSync(testDir)) {
fs.rmSync(testDir, { recursive: true, force: true });
}
});
it("should analyze a linked pair and extract a lesson", async () => {
const store = EventStore.getInstance();
const db = (store as any).db;
// Setup linked pair
store.recordPrompt({ id: "p1", repo_id: "test", client: "cli", raw_prompt: "Create login" });
db.prepare("INSERT INTO commits (id, repo_id, sha, message, committed_at) VALUES (?, ?, ?, ?, ?)").run("c1", "test", "sha1", "feat: add login", "2026-04-12T10:00:00Z");
db.prepare("INSERT INTO executions (id, prompt_id, workflow_name, executor_name, status, started_at) VALUES (?, ?, ?, ?, ?, ?)").run("e1", "p1", "test", "test", "completed", "2026-04-12T09:00:00Z");
db.prepare("INSERT INTO execution_commits (execution_id, commit_id) VALUES (?, ?)").run("e1", "c1");
const mockRequestModel = vi.fn().mockResolvedValue(JSON.stringify({
title: "Authentication Best Practice",
summary: "Always use secure headers for login.",
lesson_type: "security",
confidence: "high"
}));
const extractor = new LessonExtractor(mockRequestModel);
await extractor.extractNewLessons();
expect(mockRequestModel).toHaveBeenCalled();
const lesson = db.prepare("SELECT * FROM lessons WHERE prompt_id = ?").get("p1");
expect(lesson).toBeDefined();
expect(lesson.title).toBe("Authentication Best Practice");
});
it("should not learn from failed executions", async () => {
const store = EventStore.getInstance();
const db = (store as any).db;
store.recordPrompt({ id: "p-failed", repo_id: "test", client: "cli", raw_prompt: "Broken task" });
db.prepare("INSERT INTO commits (id, repo_id, sha, message, committed_at) VALUES (?, ?, ?, ?, ?)")
.run("c-failed", "test", "sha-failed", "fix: failed attempt", "2026-04-12T10:00:00Z");
db.prepare("INSERT INTO executions (id, prompt_id, workflow_name, executor_name, status, started_at) VALUES (?, ?, ?, ?, ?, ?)")
.run("e-failed", "p-failed", "test", "test", "failed", "2026-04-12T09:00:00Z");
db.prepare("INSERT INTO execution_commits (execution_id, commit_id) VALUES (?, ?)")
.run("e-failed", "c-failed");
const mockRequestModel = vi.fn();
await new LessonExtractor(mockRequestModel).extractNewLessons();
expect(mockRequestModel).not.toHaveBeenCalled();
expect(db.prepare("SELECT * FROM lessons WHERE prompt_id = ?").get("p-failed")).toBeUndefined();
});
it("does not record a lesson when the model is unavailable or returns malformed output", async () => {
const store = EventStore.getInstance();
const db = (store as any).db;
store.recordPrompt({ id: "p-model", repo_id: "test", client: "cli", raw_prompt: "Create model test" });
store.recordCommit({
id: "c-model",
repo_id: "test",
sha: "sha-model",
author: "test",
message: "test: model",
committed_at: "2026-04-12T10:00:00Z",
});
store.recordExecution({
id: "e-model",
prompt_id: "p-model",
workflow_name: "test",
executor_name: "test",
status: "completed",
});
store.linkCommitToExecution("e-model", "c-model");
const request = vi.fn().mockResolvedValueOnce(null).mockResolvedValueOnce("not json");
const extractor = new LessonExtractor(request);
await extractor.extractNewLessons();
await extractor.extractNewLessons();
expect(request).toHaveBeenCalledTimes(2);
expect(db.prepare("SELECT * FROM lessons WHERE prompt_id = ?").get("p-model")).toBeUndefined();
});
});