Source identity
| Field | Recorded value |
|---|---|
| Source type | GitHub source |
| Original record | Janady13/thatdeveloperguy-website / tests/unit/rive-mcp.test.ts |
| Date | Not specified in source |
| Repository | Janady13/thatdeveloperguy-website |
| Revision | 2bea2ebdff0e34494bff597d4fa9c8422a0c3a94 |
| Branch | main |
| Path or archive member | tests/unit/rive-mcp.test.ts |
| Original SHA-256 | 03c31b8ac85e4c970da004751be71281b56631216e21a75a14964e103afb1dcc |
| Git blob SHA | 7d7c8204737777a772d149afdd86a2a3a43525c3 |
| Reading-copy SHA-256 | 03c31b8ac85e4c970da004751be71281b56631216e21a75a14964e103afb1dcc |
Recovered source transcript
Download complete source text ↓55 lines · 2.9 KB
import { test } from 'node:test';
import assert from 'node:assert/strict';
import { createServer } from 'node:http';
import { mkdtempSync, readFileSync, writeFileSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import { RiveEditor } from '../../tools/rive-mcp.ts';
function stub(handler: (req: any) => any) {
const server = createServer((req, res) => {
let body = ''; req.on('data', c => body += c); req.on('end', () => {
const rpc = JSON.parse(body);
if (rpc.id === undefined) { res.statusCode = 202; res.end(); return; } // notification
const result = handler(rpc);
res.setHeader('content-type', 'text/event-stream');
res.end(`event: message\ndata: ${JSON.stringify({ jsonrpc: '2.0', id: rpc.id, result })}\n\n`);
});
});
return new Promise<{ url: string; close: () => void }>(resolve => server.listen(0, '127.0.0.1', () => resolve({ url: `http://127.0.0.1:${(server.address() as any).port}/mcp`, close: () => server.close() })));
}
test('call parses SSE-framed JSON text content and throws on isError', async () => {
const seen: any[] = [];
const s = await stub(rpc => {
seen.push(rpc);
if (rpc.method === 'initialize') return { serverInfo: { name: 'rive', version: '0.6' } };
if (rpc.params.name === 'bad') return { isError: true, content: [{ type: 'text', text: 'Error: nope' }] };
return { content: [{ type: 'text', text: JSON.stringify({ success: true, echo: rpc.params.arguments }) }] };
});
const editor = new RiveEditor(s.url);
assert.deepEqual(await editor.initialize(), { name: 'rive', version: '0.6' });
assert.deepEqual(await editor.call('list_artboards', { a: 1 }), { success: true, echo: { a: 1 } });
await assert.rejects(editor.call('bad'), /nope/);
assert.equal(seen[1].params.name, 'list_artboards'); // notifications never reach the handler
s.close();
});
test('uploadSvg sends a data URI and exportRiv writes decoded bytes', async () => {
const dir = mkdtempSync(join(tmpdir(), 'tdg-mcp-'));
writeFileSync(join(dir, 'x.svg'), '<svg xmlns="http://www.w3.org/2000/svg"/>');
let uploaded = '';
const s = await stub(rpc => {
if (rpc.method === 'initialize') return { serverInfo: { name: 'rive', version: '0.6' } };
if (rpc.params.name === 'upload_asset') { uploaded = rpc.params.arguments.file; return { content: [{ type: 'text', text: JSON.stringify({ success: true, asset: { id: '0-14' } }) }] }; }
if (rpc.params.name === 'export_file') return { content: [{ type: 'text', text: JSON.stringify({ success: true, filename: 'x.riv', data: Buffer.from('RIVE').toString('base64') }) }] };
throw new Error('unexpected');
});
const editor = new RiveEditor(s.url);
assert.equal(await editor.uploadSvg(join(dir, 'x.svg'), 'x'), '0-14');
assert.match(uploaded, /^data:image\/svg\+xml;name=x\.svg;base64,/);
const out = await editor.exportRiv(dir);
assert.equal(readFileSync(out.path, 'utf8'), 'RIVE'); assert.equal(out.bytes, 4);
s.close();
});