test(editor): web serial readuntil buffer regression
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
69
static/web_serial_readuntil_test.mjs
Normal file
69
static/web_serial_readuntil_test.mjs
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
/**
|
||||||
|
* Node regression tests for Web Serial readUntil buffer handling.
|
||||||
|
* Run: node led-tool/static/web_serial_readuntil_test.mjs
|
||||||
|
*/
|
||||||
|
|
||||||
|
function bytesIndexOf(buf, suffix) {
|
||||||
|
if (!suffix.length) return 0;
|
||||||
|
if (buf.length < suffix.length) return -1;
|
||||||
|
for (let i = 0; i <= buf.length - suffix.length; i += 1) {
|
||||||
|
let ok = true;
|
||||||
|
for (let j = 0; j < suffix.length; j += 1) {
|
||||||
|
if (buf[i + j] !== suffix[j]) {
|
||||||
|
ok = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ok) return i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
function readUntilConsume(rxBuf, suffixBytes) {
|
||||||
|
const idx = bytesIndexOf(rxBuf, suffixBytes);
|
||||||
|
if (idx < 0) return null;
|
||||||
|
const end = idx + suffixBytes.length;
|
||||||
|
const matched = rxBuf.slice(0, end);
|
||||||
|
rxBuf.splice(0, end);
|
||||||
|
return matched;
|
||||||
|
}
|
||||||
|
|
||||||
|
function enc(s) {
|
||||||
|
return [...new TextEncoder().encode(s)];
|
||||||
|
}
|
||||||
|
|
||||||
|
function assert(cond, msg) {
|
||||||
|
if (!cond) throw new Error(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
const RAW = 'raw REPL; CTRL-B to exit\r\n';
|
||||||
|
const SOFT = 'soft reboot\r\n';
|
||||||
|
|
||||||
|
// Old bug: one chunk with soft reboot + banner; suffix-at-end + clear-all loses banner.
|
||||||
|
{
|
||||||
|
const rx = enc(`MPY: ${SOFT}${RAW}boot.py line\r\n`);
|
||||||
|
const soft = enc(SOFT);
|
||||||
|
const m1 = readUntilConsume(rx, soft);
|
||||||
|
assert(m1 !== null, 'soft reboot should match');
|
||||||
|
const banner = enc(RAW);
|
||||||
|
const m2 = readUntilConsume(rx, banner);
|
||||||
|
assert(m2 !== null, 'banner must remain in buffer after soft reboot match');
|
||||||
|
assert(rx.length > 0, 'boot.py tail should remain after banner');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Banner anywhere in buffer, not only at end.
|
||||||
|
{
|
||||||
|
const rx = enc(`noise${RAW}>>> `);
|
||||||
|
const banner = enc(RAW);
|
||||||
|
const m = readUntilConsume(rx, banner);
|
||||||
|
assert(m !== null, 'banner should match mid-buffer');
|
||||||
|
}
|
||||||
|
|
||||||
|
// MPY: soft reboot marker
|
||||||
|
{
|
||||||
|
const rx = enc(`MPY: ${SOFT}`);
|
||||||
|
const soft = enc('MPY: soft reboot\r\n');
|
||||||
|
assert(readUntilConsume(rx, soft) !== null, 'MPY soft reboot marker');
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('web_serial_readuntil_test: ok');
|
||||||
Reference in New Issue
Block a user