@iceinvein/agent-skills 0.23.9 → 0.23.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/skills/index.json +2 -2
- package/skills/magpie/SKILL.md +21 -20
- package/skills/magpie/bin/magpie.ts +63 -2
- package/skills/magpie/evals/quality/README.md +74 -1
- package/skills/magpie/evals/quality/__tests__/probe-specialist.test.ts +498 -0
- package/skills/magpie/evals/quality/__tests__/replay-full.test.ts +9 -0
- package/skills/magpie/evals/quality/probe-specialist.ts +672 -0
- package/skills/magpie/evals/quality/replay-full.ts +6 -2
- package/skills/magpie/fixtures/fake-gh-with-lockfile.sh +37 -2
- package/skills/magpie/fixtures/fake-gh.sh +49 -2
- package/skills/magpie/references/critic.md +20 -4
- package/skills/magpie/references/proof.md +102 -0
- package/skills/magpie/references/scout.md +6 -1
- package/skills/magpie/references/specialists.md +15 -9
- package/skills/magpie/scripts/__tests__/cleanup-cmd.test.ts +103 -7
- package/skills/magpie/scripts/__tests__/cli.test.ts +69 -0
- package/skills/magpie/scripts/__tests__/critic-cmd.test.ts +46 -0
- package/skills/magpie/scripts/__tests__/critic.test.ts +11 -1
- package/skills/magpie/scripts/__tests__/dedupe-cmd.test.ts +20 -1
- package/skills/magpie/scripts/__tests__/git-diff.test.ts +23 -4
- package/skills/magpie/scripts/__tests__/handoff-cmd.test.ts +68 -0
- package/skills/magpie/scripts/__tests__/history.test.ts +232 -0
- package/skills/magpie/scripts/__tests__/impact-cmd.test.ts +477 -0
- package/skills/magpie/scripts/__tests__/impact-render.test.ts +365 -0
- package/skills/magpie/scripts/__tests__/impact.test.ts +915 -0
- package/skills/magpie/scripts/__tests__/incremental.test.ts +59 -8
- package/skills/magpie/scripts/__tests__/pipeline-e2e.test.ts +1 -1
- package/skills/magpie/scripts/__tests__/post-cmd.test.ts +58 -0
- package/skills/magpie/scripts/__tests__/pr-activity.test.ts +281 -0
- package/skills/magpie/scripts/__tests__/preview-cmd.test.ts +4 -4
- package/skills/magpie/scripts/__tests__/previous-findings.test.ts +267 -0
- package/skills/magpie/scripts/__tests__/proof-cmd.test.ts +260 -0
- package/skills/magpie/scripts/__tests__/proof.test.ts +226 -0
- package/skills/magpie/scripts/__tests__/refresh.test.ts +71 -0
- package/skills/magpie/scripts/__tests__/render-annotation.test.ts +34 -0
- package/skills/magpie/scripts/__tests__/render-findings.test.ts +75 -0
- package/skills/magpie/scripts/__tests__/render-progress.test.ts +9 -0
- package/skills/magpie/scripts/__tests__/setup-cmd.test.ts +376 -1
- package/skills/magpie/scripts/__tests__/shard-coverage.test.ts +79 -0
- package/skills/magpie/scripts/__tests__/skill-lint.test.ts +48 -2
- package/skills/magpie/scripts/__tests__/status-cmd.test.ts +20 -8
- package/skills/magpie/scripts/__tests__/types.test.ts +46 -0
- package/skills/magpie/scripts/cleanup-cmd.ts +88 -0
- package/skills/magpie/scripts/critic-cmd.ts +2 -0
- package/skills/magpie/scripts/critic.ts +4 -0
- package/skills/magpie/scripts/dedupe-cmd.ts +4 -0
- package/skills/magpie/scripts/evidence-filter.ts +10 -0
- package/skills/magpie/scripts/git-diff.ts +50 -19
- package/skills/magpie/scripts/handoff-cmd.ts +42 -3
- package/skills/magpie/scripts/history.ts +143 -0
- package/skills/magpie/scripts/impact-cmd.ts +202 -0
- package/skills/magpie/scripts/impact-render.ts +158 -0
- package/skills/magpie/scripts/impact.ts +622 -0
- package/skills/magpie/scripts/incremental.ts +44 -5
- package/skills/magpie/scripts/labels-cmd.ts +7 -3
- package/skills/magpie/scripts/post-cmd.ts +46 -0
- package/skills/magpie/scripts/pr-activity.ts +243 -0
- package/skills/magpie/scripts/preview-cmd.ts +3 -0
- package/skills/magpie/scripts/previous-findings.ts +181 -0
- package/skills/magpie/scripts/proof-cmd.ts +226 -0
- package/skills/magpie/scripts/proof.ts +150 -0
- package/skills/magpie/scripts/refresh.ts +11 -0
- package/skills/magpie/scripts/render-annotation.ts +17 -0
- package/skills/magpie/scripts/render-cmd.ts +12 -0
- package/skills/magpie/scripts/render-findings.ts +37 -1
- package/skills/magpie/scripts/render-progress.ts +3 -0
- package/skills/magpie/scripts/setup-cmd.ts +142 -11
- package/skills/magpie/scripts/shard-coverage.ts +53 -0
- package/skills/magpie/scripts/status-cmd.ts +2 -0
- package/skills/magpie/scripts/types.ts +39 -0
- package/skills/magpie/skill.json +1 -1
- package/skills/magpie/templates/styles.css +30 -0
- package/skills/sluice/scripts/status.sh +32 -13
- package/skills/sluice/skill.json +1 -1
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
import { describe, expect, test } from 'bun:test'
|
|
2
|
+
import type { ImpactMap } from '../impact.ts'
|
|
3
|
+
import {
|
|
4
|
+
IMPACT_BRIEF_CAP_BYTES,
|
|
5
|
+
IMPACT_BRIEF_MAX_CHILDREN,
|
|
6
|
+
renderImpactMarkdown,
|
|
7
|
+
} from '../impact-render.ts'
|
|
8
|
+
|
|
9
|
+
// Entries are deliberately out of render order so the tests pin the sort.
|
|
10
|
+
function sampleMap(): ImpactMap {
|
|
11
|
+
return {
|
|
12
|
+
version: 1,
|
|
13
|
+
symbols: [
|
|
14
|
+
{
|
|
15
|
+
name: 'formatTotal',
|
|
16
|
+
kind: 'added',
|
|
17
|
+
definedAt: [{ file: 'src/total.ts', line: 3 }],
|
|
18
|
+
shard: 1,
|
|
19
|
+
hits: 1,
|
|
20
|
+
references: [{ file: 'src/cart.ts', line: 7, text: 'formatTotal(cart)' }],
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
name: 'render',
|
|
24
|
+
kind: 'changed',
|
|
25
|
+
definedAt: [{ file: 'src/view.ts', line: 1 }],
|
|
26
|
+
shard: 1,
|
|
27
|
+
hits: 230,
|
|
28
|
+
references: [],
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
name: 'loadUser',
|
|
32
|
+
kind: 'changed',
|
|
33
|
+
definedAt: [{ file: 'src/user.ts', line: 5 }],
|
|
34
|
+
shard: 0,
|
|
35
|
+
hits: 30,
|
|
36
|
+
references: [
|
|
37
|
+
{ file: 'src/api.ts', line: 2, text: 'loadUser(id)' },
|
|
38
|
+
{ file: 'src/page.ts', line: 8, text: 'await loadUser(params.id)' },
|
|
39
|
+
],
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
name: 'parseRow',
|
|
43
|
+
kind: 'removed',
|
|
44
|
+
definedAt: [{ file: 'src/a.ts', line: 2 }],
|
|
45
|
+
shard: 1,
|
|
46
|
+
hits: 1,
|
|
47
|
+
references: [{ file: 'src/b.ts', line: 9, text: 'parseRow(r)' }],
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
uses: [
|
|
51
|
+
{
|
|
52
|
+
name: 'getConfig',
|
|
53
|
+
usedIn: { file: 'src/user.ts', line: 12 },
|
|
54
|
+
shard: 0,
|
|
55
|
+
definedAt: [{ file: 'lib/config.ts', line: 1, text: 'export function getConfig() {' }],
|
|
56
|
+
},
|
|
57
|
+
],
|
|
58
|
+
stores: [
|
|
59
|
+
{
|
|
60
|
+
name: 'orders',
|
|
61
|
+
kind: 'table',
|
|
62
|
+
usedIn: [{ file: 'src/db.ts', line: 10 }],
|
|
63
|
+
shard: 0,
|
|
64
|
+
writers: [{ file: 'jobs/sync.ts', line: 4, text: 'INSERT INTO orders (id) VALUES (1)' }],
|
|
65
|
+
},
|
|
66
|
+
],
|
|
67
|
+
routes: [
|
|
68
|
+
{
|
|
69
|
+
path: '/api/users/:id',
|
|
70
|
+
usedIn: { file: 'src/routes.ts', line: 20 },
|
|
71
|
+
shard: 1,
|
|
72
|
+
siblings: [{ file: 'src/admin.ts', line: 3, text: "router.get('/api/users', list)" }],
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
docs: [
|
|
76
|
+
{
|
|
77
|
+
file: 'docs/user.md',
|
|
78
|
+
line: 4,
|
|
79
|
+
text: 'Call loadUser before render.',
|
|
80
|
+
mentions: ['loadUser', 'render'],
|
|
81
|
+
shards: [1],
|
|
82
|
+
},
|
|
83
|
+
],
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function emptyMap(): ImpactMap {
|
|
88
|
+
return { version: 1, symbols: [], uses: [], stores: [], routes: [], docs: [] }
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const FULL = `### Other writers of the same data
|
|
92
|
+
- \`orders\` (diff: src/db.ts:10)
|
|
93
|
+
- jobs/sync.ts:4 \`INSERT INTO orders (id) VALUES (1)\`
|
|
94
|
+
|
|
95
|
+
### References to changed symbols
|
|
96
|
+
- \`parseRow\` (diff: src/a.ts:2)
|
|
97
|
+
- src/b.ts:9 \`parseRow(r)\`
|
|
98
|
+
- \`loadUser\` (diff: src/user.ts:5)
|
|
99
|
+
- src/api.ts:2 \`loadUser(id)\`
|
|
100
|
+
- src/page.ts:8 \`await loadUser(params.id)\`
|
|
101
|
+
- 2 of 30 shown
|
|
102
|
+
- \`render\`: 230 hits, too common to list
|
|
103
|
+
|
|
104
|
+
### References to added symbols
|
|
105
|
+
- \`formatTotal\` (diff: src/total.ts:3)
|
|
106
|
+
- src/cart.ts:7 \`formatTotal(cart)\`
|
|
107
|
+
|
|
108
|
+
### Definitions this change relies on
|
|
109
|
+
- \`getConfig\` (diff: src/user.ts:12)
|
|
110
|
+
- lib/config.ts:1 \`export function getConfig() {\`
|
|
111
|
+
|
|
112
|
+
### Sibling routes
|
|
113
|
+
- \`/api/users/:id\` (diff: src/routes.ts:20)
|
|
114
|
+
- src/admin.ts:3 \`router.get('/api/users', list)\`
|
|
115
|
+
|
|
116
|
+
### Docs naming what changed
|
|
117
|
+
- docs/user.md:4 \`Call loadUser before render.\` (names: loadUser, render)`
|
|
118
|
+
|
|
119
|
+
const SHARD_0 = `### Other writers of the same data
|
|
120
|
+
- \`orders\` (diff: src/db.ts:10)
|
|
121
|
+
- jobs/sync.ts:4 \`INSERT INTO orders (id) VALUES (1)\`
|
|
122
|
+
|
|
123
|
+
### References to changed symbols
|
|
124
|
+
- \`loadUser\` (diff: src/user.ts:5)
|
|
125
|
+
- src/api.ts:2 \`loadUser(id)\`
|
|
126
|
+
- src/page.ts:8 \`await loadUser(params.id)\`
|
|
127
|
+
- 2 of 30 shown
|
|
128
|
+
|
|
129
|
+
### Definitions this change relies on
|
|
130
|
+
- \`getConfig\` (diff: src/user.ts:12)
|
|
131
|
+
- lib/config.ts:1 \`export function getConfig() {\``
|
|
132
|
+
|
|
133
|
+
const SHARD_0_CUT_AFTER_TWO = `### Other writers of the same data
|
|
134
|
+
- \`orders\` (diff: src/db.ts:10)
|
|
135
|
+
- jobs/sync.ts:4 \`INSERT INTO orders (id) VALUES (1)\`
|
|
136
|
+
|
|
137
|
+
### References to changed symbols
|
|
138
|
+
- \`loadUser\` (diff: src/user.ts:5)
|
|
139
|
+
- src/api.ts:2 \`loadUser(id)\`
|
|
140
|
+
- src/page.ts:8 \`await loadUser(params.id)\`
|
|
141
|
+
- 2 of 30 shown
|
|
142
|
+
|
|
143
|
+
1 more entries in impact.json`
|
|
144
|
+
|
|
145
|
+
const bytes = (s: string): number => Buffer.byteLength(s, 'utf8')
|
|
146
|
+
|
|
147
|
+
describe('renderImpactMarkdown', () => {
|
|
148
|
+
test('renders every entry in section order with shard null', () => {
|
|
149
|
+
expect(renderImpactMarkdown(sampleMap(), { shard: null, capBytes: 100_000 })).toBe(FULL)
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
test('renders only the entries of the requested shard', () => {
|
|
153
|
+
expect(renderImpactMarkdown(sampleMap(), { shard: 0, capBytes: 100_000 })).toBe(SHARD_0)
|
|
154
|
+
})
|
|
155
|
+
|
|
156
|
+
test('returns an empty string when no entry matches the shard', () => {
|
|
157
|
+
expect(renderImpactMarkdown(sampleMap(), { shard: 5, capBytes: 100_000 })).toBe('')
|
|
158
|
+
})
|
|
159
|
+
|
|
160
|
+
test('returns an empty string for an empty map', () => {
|
|
161
|
+
expect(renderImpactMarkdown(emptyMap(), { shard: null, capBytes: 100_000 })).toBe('')
|
|
162
|
+
})
|
|
163
|
+
|
|
164
|
+
test('keeps whole entries that fit the cap and counts the rest', () => {
|
|
165
|
+
const capBytes = bytes(SHARD_0_CUT_AFTER_TWO)
|
|
166
|
+
expect(renderImpactMarkdown(sampleMap(), { shard: 0, capBytes })).toBe(SHARD_0_CUT_AFTER_TWO)
|
|
167
|
+
})
|
|
168
|
+
|
|
169
|
+
test('skips an entry too big for the cap and keeps a later one that fits', () => {
|
|
170
|
+
const map = emptyMap()
|
|
171
|
+
for (const [name, text] of [
|
|
172
|
+
['aaaa', 'write(aaaa)'],
|
|
173
|
+
['bbbb', 'y'.repeat(300)],
|
|
174
|
+
['cccc', 'write(cccc)'],
|
|
175
|
+
] as const) {
|
|
176
|
+
map.stores.push({
|
|
177
|
+
name,
|
|
178
|
+
kind: 'file',
|
|
179
|
+
usedIn: [{ file: `${name}.ts`, line: 1 }],
|
|
180
|
+
shard: null,
|
|
181
|
+
writers: [{ file: 'w.ts', line: 1, text }],
|
|
182
|
+
})
|
|
183
|
+
}
|
|
184
|
+
expect(renderImpactMarkdown(map, { shard: null, capBytes: 200 })).toBe(
|
|
185
|
+
`### Other writers of the same data
|
|
186
|
+
- \`aaaa\` (diff: aaaa.ts:1)
|
|
187
|
+
- w.ts:1 \`write(aaaa)\`
|
|
188
|
+
- \`cccc\` (diff: cccc.ts:1)
|
|
189
|
+
- w.ts:1 \`write(cccc)\`
|
|
190
|
+
|
|
191
|
+
1 more entries in impact.json`,
|
|
192
|
+
)
|
|
193
|
+
})
|
|
194
|
+
|
|
195
|
+
test('limits each entry to maxChildren and says how many were shown', () => {
|
|
196
|
+
const refText = (i: number): string => `${'z'.repeat(116)}(${String(i).padStart(2, '0')})`
|
|
197
|
+
const twelveRefs = (file: string) =>
|
|
198
|
+
Array.from({ length: 12 }, (_, i) => ({ file, line: i + 1, text: refText(i + 1) }))
|
|
199
|
+
const map = emptyMap()
|
|
200
|
+
map.symbols.push(
|
|
201
|
+
{
|
|
202
|
+
name: 'alpha',
|
|
203
|
+
kind: 'changed',
|
|
204
|
+
definedAt: [{ file: 'src/a.ts', line: 1 }],
|
|
205
|
+
shard: null,
|
|
206
|
+
hits: 12,
|
|
207
|
+
references: twelveRefs('src/ra.ts'),
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
name: 'beta',
|
|
211
|
+
kind: 'changed',
|
|
212
|
+
definedAt: [{ file: 'src/b.ts', line: 1 }],
|
|
213
|
+
shard: null,
|
|
214
|
+
hits: 12,
|
|
215
|
+
references: twelveRefs('src/rb.ts'),
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
name: 'gamma',
|
|
219
|
+
kind: 'changed',
|
|
220
|
+
definedAt: [{ file: 'src/c.ts', line: 1 }],
|
|
221
|
+
shard: null,
|
|
222
|
+
hits: 1,
|
|
223
|
+
references: [{ file: 'src/g.ts', line: 5, text: 'gamma()' }],
|
|
224
|
+
},
|
|
225
|
+
)
|
|
226
|
+
const z = 'z'.repeat(116)
|
|
227
|
+
expect(
|
|
228
|
+
renderImpactMarkdown(map, {
|
|
229
|
+
shard: null,
|
|
230
|
+
capBytes: IMPACT_BRIEF_CAP_BYTES,
|
|
231
|
+
maxChildren: IMPACT_BRIEF_MAX_CHILDREN,
|
|
232
|
+
}),
|
|
233
|
+
).toBe(`### References to changed symbols
|
|
234
|
+
- \`alpha\` (diff: src/a.ts:1)
|
|
235
|
+
- src/ra.ts:1 \`${z}(01)\`
|
|
236
|
+
- src/ra.ts:2 \`${z}(02)\`
|
|
237
|
+
- src/ra.ts:3 \`${z}(03)\`
|
|
238
|
+
- 3 of 12 shown
|
|
239
|
+
- \`beta\` (diff: src/b.ts:1)
|
|
240
|
+
- src/rb.ts:1 \`${z}(01)\`
|
|
241
|
+
- src/rb.ts:2 \`${z}(02)\`
|
|
242
|
+
- src/rb.ts:3 \`${z}(03)\`
|
|
243
|
+
- 3 of 12 shown
|
|
244
|
+
- \`gamma\` (diff: src/c.ts:1)
|
|
245
|
+
- src/g.ts:5 \`gamma()\``)
|
|
246
|
+
})
|
|
247
|
+
|
|
248
|
+
test('counts children of a non-symbol entry against their own number', () => {
|
|
249
|
+
const map = emptyMap()
|
|
250
|
+
map.routes.push({
|
|
251
|
+
path: '/api/x',
|
|
252
|
+
usedIn: { file: 'r.ts', line: 1 },
|
|
253
|
+
shard: null,
|
|
254
|
+
siblings: [
|
|
255
|
+
{ file: 's.ts', line: 1, text: 'a' },
|
|
256
|
+
{ file: 's.ts', line: 2, text: 'b' },
|
|
257
|
+
],
|
|
258
|
+
})
|
|
259
|
+
expect(renderImpactMarkdown(map, { shard: null, capBytes: 1000, maxChildren: 1 })).toBe(
|
|
260
|
+
`### Sibling routes
|
|
261
|
+
- \`/api/x\` (diff: r.ts:1)
|
|
262
|
+
- s.ts:1 \`a\`
|
|
263
|
+
- 1 of 2 shown`,
|
|
264
|
+
)
|
|
265
|
+
})
|
|
266
|
+
|
|
267
|
+
test('throws naming the cap when the cap cannot hold the count line', () => {
|
|
268
|
+
expect(() => renderImpactMarkdown(sampleMap(), { shard: null, capBytes: 10 })).toThrow('10')
|
|
269
|
+
})
|
|
270
|
+
|
|
271
|
+
test('wraps text containing a backtick in a double-backtick span', () => {
|
|
272
|
+
const map = emptyMap()
|
|
273
|
+
map.routes.push({
|
|
274
|
+
path: '/api/:id',
|
|
275
|
+
usedIn: { file: 'r.ts', line: 1 },
|
|
276
|
+
shard: null,
|
|
277
|
+
siblings: [{ file: 's.ts', line: 4, text: `const u = \`/api/\${id}\`` }],
|
|
278
|
+
})
|
|
279
|
+
expect(renderImpactMarkdown(map, { shard: null, capBytes: 1000 })).toBe(
|
|
280
|
+
`### Sibling routes
|
|
281
|
+
- \`/api/:id\` (diff: r.ts:1)
|
|
282
|
+
- s.ts:4 \`\` const u = \`/api/\${id}\` \`\``,
|
|
283
|
+
)
|
|
284
|
+
})
|
|
285
|
+
|
|
286
|
+
test('leaves out entries with no facts outside the diff, without counting them', () => {
|
|
287
|
+
const map = emptyMap()
|
|
288
|
+
map.stores.push({
|
|
289
|
+
name: 'orders',
|
|
290
|
+
kind: 'table',
|
|
291
|
+
usedIn: [{ file: 'a.ts', line: 1 }],
|
|
292
|
+
shard: null,
|
|
293
|
+
writers: [],
|
|
294
|
+
})
|
|
295
|
+
map.routes.push({ path: '/x', usedIn: { file: 'a.ts', line: 2 }, shard: null, siblings: [] })
|
|
296
|
+
map.uses.push({
|
|
297
|
+
name: 'getUser',
|
|
298
|
+
usedIn: { file: 'a.ts', line: 3 },
|
|
299
|
+
shard: null,
|
|
300
|
+
definedAt: [],
|
|
301
|
+
})
|
|
302
|
+
map.symbols.push(
|
|
303
|
+
{
|
|
304
|
+
name: 'lonely',
|
|
305
|
+
kind: 'added',
|
|
306
|
+
definedAt: [{ file: 'a.ts', line: 4 }],
|
|
307
|
+
shard: null,
|
|
308
|
+
hits: 0,
|
|
309
|
+
references: [],
|
|
310
|
+
},
|
|
311
|
+
{
|
|
312
|
+
name: 'render',
|
|
313
|
+
kind: 'changed',
|
|
314
|
+
definedAt: [{ file: 'a.ts', line: 5 }],
|
|
315
|
+
shard: null,
|
|
316
|
+
hits: 300,
|
|
317
|
+
references: [],
|
|
318
|
+
},
|
|
319
|
+
)
|
|
320
|
+
map.docs.push({
|
|
321
|
+
file: 'README.md',
|
|
322
|
+
line: 1,
|
|
323
|
+
text: 'see render',
|
|
324
|
+
mentions: ['render'],
|
|
325
|
+
shards: [],
|
|
326
|
+
})
|
|
327
|
+
expect(renderImpactMarkdown(map, { shard: null, capBytes: 1000 })).toBe(
|
|
328
|
+
`### References to changed symbols
|
|
329
|
+
- \`render\`: 300 hits, too common to list
|
|
330
|
+
|
|
331
|
+
### Docs naming what changed
|
|
332
|
+
- README.md:1 \`see render\` (names: render)`,
|
|
333
|
+
)
|
|
334
|
+
})
|
|
335
|
+
|
|
336
|
+
test('renders a doc in each shard it names', () => {
|
|
337
|
+
const map = emptyMap()
|
|
338
|
+
map.docs.push({ file: 'd.md', line: 2, text: 'see jobs', mentions: ['jobs'], shards: [2, 4] })
|
|
339
|
+
expect(renderImpactMarkdown(map, { shard: 4, capBytes: 1000 })).toBe(
|
|
340
|
+
'### Docs naming what changed\n- d.md:2 `see jobs` (names: jobs)',
|
|
341
|
+
)
|
|
342
|
+
})
|
|
343
|
+
|
|
344
|
+
test('leaves a doc out of a shard it does not name', () => {
|
|
345
|
+
const map = emptyMap()
|
|
346
|
+
map.docs.push({ file: 'd.md', line: 2, text: 'see jobs', mentions: ['jobs'], shards: [2, 4] })
|
|
347
|
+
expect(renderImpactMarkdown(map, { shard: 3, capBytes: 1000 })).toBe('')
|
|
348
|
+
})
|
|
349
|
+
|
|
350
|
+
test('counts the cap in UTF-8 bytes, not characters', () => {
|
|
351
|
+
const map = emptyMap()
|
|
352
|
+
map.stores.push({
|
|
353
|
+
name: 'cafés',
|
|
354
|
+
kind: 'file',
|
|
355
|
+
usedIn: [{ file: 'a.ts', line: 1 }],
|
|
356
|
+
shard: null,
|
|
357
|
+
writers: [{ file: 'b.ts', line: 2, text: "write('cafés')" }],
|
|
358
|
+
})
|
|
359
|
+
const whole =
|
|
360
|
+
"### Other writers of the same data\n- `cafés` (diff: a.ts:1)\n - b.ts:2 `write('cafés')`"
|
|
361
|
+
expect(renderImpactMarkdown(map, { shard: null, capBytes: whole.length })).toBe(
|
|
362
|
+
'1 more entries in impact.json',
|
|
363
|
+
)
|
|
364
|
+
})
|
|
365
|
+
})
|