feat(discord): post a Markdown table as an aligned code block

This commit is contained in:
Devvyn committed 2026-10-30 19:58:44 +08:00
1 parent 093f242662
commit e5d82eb044
3 files changed
+112 -2

No files matched your search

+63
View File
@@ -25,6 +25,7 @@ import {
safeAttachmentName,
screenTail,
splitForDiscord,
tablesToCodeBlocks,
DEFAULT_DISCORD_CONFIG,
DiscordApi,
DiscordBridge,
@@ -579,6 +580,24 @@ describe('DiscordBridge', () => {
b.stop();
});
it('posts a Markdown table as an aligned code block, since Discord does not render tables', async () => {
const b = bridge();
const table = [
'| Variant | Decode (tokens/s) |',
'|---|---:|',
'| kv-f16 | 557.0 |',
'| n-gram mod | 550.2 |',
].join('\n');
await b.notify({ ...MSG, fullText: async () => `Results:\n\n${table}` });
const posted = posts
.filter((p) => p.path.endsWith('/messages'))
.map((p) => String(p.body?.content))
.join('\n');
expect(posted).toContain('```\nVariant Decode (tokens/s)\n');
expect(posted).not.toContain('|---');
b.stop();
});
it('does not post the same message twice (idle, then stop), and falls back to the tail without a transcript', async () => {
const b = bridge();
await b.notify({ ...MSG, fullText: async () => 'Short answer.' });
@@ -1152,6 +1171,50 @@ describe('DiscordBridge files and startup hint', () => {
});
});
describe('tablesToCodeBlocks', () => {
it('turns a Markdown table into an aligned code block, dropping bold and code marks', () => {
const md = [
'Results:',
'',
'| Variant | Decode (tokens/s) |',
'|---|---:|',
'| `kv-f16` | 557.0 |',
'| **n-gram simple** | 554.5 |',
'| n-gram mod | 550.2 |',
'',
'Done.',
].join('\n');
expect(tablesToCodeBlocks(md)).toBe(
[
'Results:',
'',
'```',
'Variant Decode (tokens/s)',
'------------- -----------------',
'kv-f16 557.0',
'n-gram simple 554.5',
'n-gram mod 550.2',
'```',
'',
'Done.',
].join('\n')
);
});
it('leaves a table inside a code fence, prose with pipes and a table-less message alone', () => {
const fenced = ['```', '| a | b |', '|---|---|', '| 1 | 2 |', '```'].join('\n');
expect(tablesToCodeBlocks(fenced)).toBe(fenced);
const prose = 'Use a | b to pipe.\nThen c | d.';
expect(tablesToCodeBlocks(prose)).toBe(prose);
});
it('pads a short row and keeps an escaped pipe in a cell', () => {
const out = tablesToCodeBlocks(['| a | b |', '|---|---|', '| x \\| y |', '| p | q |'].join('\n'));
expect(out).toContain('x | y');
expect(out.split('\n').every((l) => !/\s$/.test(l))).toBe(true);
});
});
describe('splitForDiscord', () => {
it('keeps a short message whole', () => {
expect(splitForDiscord('Line one\n\n**Two**\n- a\n- b')).toEqual(['Line one\n\n**Two**\n- a\n- b']);