53 lines
3.1 KiB
JavaScript
53 lines
3.1 KiB
JavaScript
import assert from 'node:assert/strict';
|
|
import {before,after,test} from 'node:test';
|
|
import {createServer} from 'vite';
|
|
let server,series,segments,frames,localPreview,MEDIA_PROTOCOL;
|
|
before(async()=>{
|
|
server=await createServer({appType:'custom',logLevel:'silent',server:{middlewareMode:true}});
|
|
({monitorSeries:series}=await server.ssrLoadModule('/src/core/fleet/boardMonitor.ts'));
|
|
({lineSegments:segments}=await server.ssrLoadModule('/src/components/system/TelemetrySeries.tsx'));
|
|
({MEDIA_PROTOCOL}=await server.ssrLoadModule('@xgrids-k1/frontend/sensors/previewFrames.ts'));
|
|
({localPreviewFrames:frames,localPreview}=await server.ssrLoadModule('@xgrids-k1/frontend/sensors/localPreview.ts'));
|
|
});
|
|
after(async()=>{await server?.close();});
|
|
test('archive gaps break the plot instead of manufacturing zero or connecting missing time',()=>{
|
|
const values=series({start:0,end:20,bucket_seconds:5,series:[{at:0,max:80},{at:5,max:90},{at:20,max:10}]},'max');
|
|
assert.deepEqual(values,[80,90,null,null,10]);
|
|
const result=segments(values,100);
|
|
assert.equal(result.length,2);
|
|
assert.match(result[0],/^0.00,8.80 25.00,5.40$/);
|
|
assert.deepEqual(segments([null,NaN,null]),[]);
|
|
});
|
|
test('HTTP media framing survives every byte boundary and refuses oversized frames',()=>{
|
|
const output=[],receive=frames((kind,bytes)=>output.push([kind,[...bytes]]));
|
|
const encoded=Uint8Array.of(2,0,0,0,3,4,5,6,3,0,0,0,2,7,8);
|
|
for(const byte of encoded)receive(Uint8Array.of(byte));
|
|
assert.deepEqual(output,[[2,[4,5,6]],[3,[7,8]]]);
|
|
assert.throws(()=>frames(()=>{})(Uint8Array.of(2,0,1,0,0)));
|
|
assert.throws(()=>frames(()=>{})(Uint8Array.of(7,0,0,0,0)));
|
|
});
|
|
|
|
test('local carrier delivers registered channels and ACKs through completed responses',async()=>{
|
|
const encode=(kind,data)=>{const bytes=typeof data==='string'?new TextEncoder().encode(data):Uint8Array.from(data);const out=new Uint8Array(bytes.length+5);out[0]=kind;new DataView(out.buffer).setUint32(1,bytes.length);out.set(bytes,5);return out;};
|
|
const peer='peer_'+ 'a'.repeat(32), received=[], closed=[];let preview;
|
|
const device={id:'synthetic-k1',snapshot:{context:{session_id:'synthetic-session'}}};
|
|
const transport={
|
|
submit:async request=>{closed.push(request);return {state:'complete'};},
|
|
localPreview:{
|
|
open:async request=>{assert.equal(request.action_id,'offer');return new Response(encode(0,JSON.stringify({peer_id:peer,media_protocol:MEDIA_PROTOCOL})));},
|
|
read:async(id,after)=>{
|
|
assert.equal(id,peer);
|
|
if(after===0)return new Response(new Uint8Array([...encode(2,[8,9]),...encode(3,'camera-ready')]));
|
|
assert.equal(after,7);preview.close();return new Response();
|
|
}
|
|
}
|
|
};
|
|
preview=localPreview(device,transport,{},()=>assert.fail('carrier failed'));
|
|
preview.rrd.onmessage=event=>{received.push([...new Uint8Array(event.data)]);preview.rrd.send(JSON.stringify({ack:7}));};
|
|
preview.camera.onmessage=event=>received.push(event.data);
|
|
await preview.start();
|
|
assert.deepEqual(received,[[8,9],'camera-ready']);
|
|
assert.equal(preview.rrd.readyState,'closed');assert.equal(closed.length,1);
|
|
assert.equal(closed[0].action_id,'close-peer');assert.equal(closed[0].parameters.peer_id,peer);
|
|
});
|