-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathparser.test.ts
More file actions
175 lines (144 loc) · 5.67 KB
/
Copy pathparser.test.ts
File metadata and controls
175 lines (144 loc) · 5.67 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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
import { describe, it } from "node:test";
import assert from "node:assert/strict";
import { parseMemoryMd } from "../parser.js";
describe("parseMemoryMd", () => {
it("parses sections from headings", () => {
const content = `# Main Title
## Active
- Item A → \`memory/a.md\`
## Products
- Item B → \`memory/b.md\`
`;
const { sections } = parseMemoryMd(content);
assert.equal(sections.length, 3);
assert.equal(sections[0].heading, "Main Title");
assert.equal(sections[0].level, 1);
assert.equal(sections[1].heading, "Active");
assert.equal(sections[1].level, 2);
assert.equal(sections[2].heading, "Products");
});
it("parses arrow references with em-dash", () => {
const content = `## Active
- AI Loadout — routing core (v1.0.3) → \`memory/ai-loadout.md\`
- Claude Rules — CLAUDE.md optimizer → \`memory/claude-rules.md\`
`;
const { refs } = parseMemoryMd(content);
assert.equal(refs.length, 2);
assert.equal(refs[0].name, "AI Loadout");
assert.equal(refs[0].description, "routing core (v1.0.3)");
assert.equal(refs[0].path, "memory/ai-loadout.md");
assert.equal(refs[1].name, "Claude Rules");
});
it("handles references without descriptions", () => {
const content = `## Section
- MyTool → \`memory/mytool.md\`
`;
const { refs } = parseMemoryMd(content);
assert.equal(refs.length, 1);
assert.equal(refs[0].name, "MyTool");
assert.equal(refs[0].description, "");
assert.equal(refs[0].path, "memory/mytool.md");
});
it("returns empty for non-list content", () => {
const content = `# Title
Just some text, no list items.
More text.
`;
const { refs } = parseMemoryMd(content);
assert.equal(refs.length, 0);
});
it("associates refs with their parent section", () => {
const content = `## Active
- Tool A → \`memory/a.md\`
- Tool B → \`memory/b.md\`
## Archived
- Tool C → \`memory/c.md\`
`;
const { sections } = parseMemoryMd(content);
assert.equal(sections[0].entries.length, 2);
assert.equal(sections[1].entries.length, 1);
assert.equal(sections[1].entries[0].name, "Tool C");
});
it("handles asterisk bullets", () => {
const content = `## Section
* Tool A — desc → \`memory/a.md\`
`;
const { refs } = parseMemoryMd(content);
assert.equal(refs.length, 1);
assert.equal(refs[0].name, "Tool A");
});
it("ignores non-reference list items", () => {
const content = `## Section
- Just a normal list item
- Another item without path
- Tool A → \`memory/a.md\`
`;
const { refs } = parseMemoryMd(content);
assert.equal(refs.length, 1);
assert.equal(refs[0].name, "Tool A");
});
it("parses non-bulleted arrow references", () => {
const content = `## Active
AI Loadout — routing core (v1.0.3) → \`memory/ai-loadout.md\`
Claude Rules — optimizer → \`memory/claude-rules.md\`
`;
const { refs } = parseMemoryMd(content);
assert.equal(refs.length, 2);
assert.equal(refs[0].name, "AI Loadout");
assert.equal(refs[0].path, "memory/ai-loadout.md");
assert.equal(refs[1].name, "Claude Rules");
});
// MEM-001 / MEM-003: prose path-citations must NOT become refs.
it("rejects prose path-citation junk shapes (MEM-001)", () => {
const content = `## Prose
- Memory files: see \`memory/index.json\` for the generated dispatch table
Full frame in \`C:/Users/Public/.claude/projects/memory/user_profile.md\` — read it if unsure
See also: the post-proof balance tuning notes live at \`memory/post-proof-balance-tuning.md\` and cover wave-based tuning
## Real
- Genuine Tool — a real entry → \`memory/genuine.md\`
`;
const { refs } = parseMemoryMd(content);
// Only the genuine bullet+arrow entry survives.
assert.equal(refs.length, 1, "exactly one ref should parse");
assert.equal(refs[0].name, "Genuine Tool");
assert.equal(refs[0].path, "memory/genuine.md");
// None of the junk shapes leak through under any derived name.
const junkNames = ["Memory files", "Full frame in", "See also"];
for (const junk of junkNames) {
assert.ok(
!refs.some((r) => r.name.startsWith(junk)),
`junk shape "${junk}" must not be parsed as a ref`,
);
}
// The kebab ids that used to leak (memory-files / full-frame / see-also)
// are absent because the lines are not parsed as refs at all.
const paths = refs.map((r) => r.path);
assert.ok(!paths.includes("memory/index.json"));
assert.ok(!paths.includes("memory/post-proof-balance-tuning.md"));
});
it("rejects absolute/glob paths reached via the inline-path branch (MEM-001)", () => {
// These lines have a bullet + arrow but the backtick path is NOT the
// arrow target (text follows it), so the well-behaved arrow branch does
// NOT match and they fall through to the inline-path branch — which is
// the branch MEM-001 tightens. Absolute and glob paths must be rejected
// there; only the relative topic ref survives.
const content = `## Edge
- Drive Path — see \`C:/Users/Public/memory/x.md\` → for more details here
- Glob Path — see \`memory/*.md\` → for all the files
- Real One — see \`memory/real.md\` → for the real one
`;
const { refs } = parseMemoryMd(content);
assert.equal(refs.length, 1);
assert.equal(refs[0].path, "memory/real.md");
});
it("still parses a genuine bullet + arrow inline-path ref (MEM-001 regression guard)", () => {
// No em-dash separator, path in backticks, bullet + arrow present.
const content = `## Active
- MyTopic → \`memory/my-topic.md\`
`;
const { refs } = parseMemoryMd(content);
assert.equal(refs.length, 1);
assert.equal(refs[0].name, "MyTopic");
assert.equal(refs[0].path, "memory/my-topic.md");
});
});