Fileservice

This commit is contained in:
chk
2026-06-14 11:18:46 +02:00
parent 319fae944a
commit a807732b58
16 changed files with 822 additions and 678 deletions

View File

@@ -0,0 +1,95 @@
// Testet das FCode-Routing in InputWS (FCodeClient wird gemockt).
jest.mock('../robot/FCodeClient', () => ({
isFCode: jest.fn((msg) => /^F[A-Z][a-z]+/.test(String(msg).trim())),
handle: jest.fn(),
}));
const http = require('http');
const WebSocket = require('ws');
const FCodeClient = require('../robot/FCodeClient');
const initInputWS = require('../server/InputWS');
const GCode = require('../robot/GCode');
const createDummyRobot = require('./helpers/createDummyRobot');
/* ---------- helpers ---------- */
function listen(server) {
return new Promise((resolve, reject) => {
server.listen(0, () => {
const { port } = server.address();
port ? resolve(port) : reject(new Error('no port'));
});
server.on('error', reject);
});
}
function connect(port) {
return new Promise((resolve, reject) => {
const ws = new WebSocket(`ws://127.0.0.1:${port}`);
ws.on('open', () => resolve(ws));
ws.on('error', reject);
});
}
function nextMessage(ws, timeoutMs = 2000) {
return new Promise((resolve, reject) => {
const t = setTimeout(() => reject(new Error('Timeout')), timeoutMs);
ws.once('message', (d) => { clearTimeout(t); resolve(d.toString()); });
});
}
/* ---------- suite ---------- */
describe('InputWS FCode-Routing', () => {
let server, ws;
beforeEach(() => {
FCodeClient.handle.mockReset();
FCodeClient.isFCode.mockClear();
});
afterEach(async () => {
if (ws) { ws.close(); ws = null; }
if (server) { await new Promise(r => server.close(r)); server = null; }
});
async function setup(robot) {
server = http.createServer();
initInputWS(server, robot || createDummyRobot(), GCode, { connectedClients: [], lastCommands: [], lastPings: [] });
const port = await listen(server);
ws = await connect(port);
return ws;
}
test('FList → broadcastet die Antwortdaten vom Fileservice', async () => {
FCodeClient.handle.mockResolvedValue({ type: 'list', data: JSON.stringify([{ id: 'a' }]) });
await setup();
const replyP = nextMessage(ws);
ws.send('FList');
expect(JSON.parse(await replyP)).toEqual([{ id: 'a' }]);
});
test('FPlus (step) → GCode-Zeile ausführen + M114 broadcasten', async () => {
const line = 'G90 G1 x10 y300 z0 a1.5708 b-1.5708 c0 e0 f1000';
FCodeClient.handle.mockResolvedValue({ type: 'step', line });
const robot = createDummyRobot();
await setup(robot);
const replyP = nextMessage(ws);
ws.send('FPlus');
const msg = JSON.parse(await replyP);
expect(msg.position).toBeDefined();
expect(robot.sendCommand).toHaveBeenCalled();
});
test('Fileservice-Fehler → machine-readable FILE_ERROR an Sender', async () => {
const err = Object.assign(new Error('not found'), { code: 'PROGRAM_NOT_FOUND' });
FCodeClient.handle.mockRejectedValue(err);
await setup();
const replyP = nextMessage(ws);
ws.send('FLoad nichtda');
const msg = JSON.parse(await replyP);
expect(msg.type).toBe('error');
expect(msg.code).toBe('FILE_ERROR');
expect(msg.input).toBe('FLoad nichtda');
});
});