From eb58cefa8e716270a42360a51c55cb1b728ff9db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Sun, 10 May 2026 20:34:43 +0200 Subject: [PATCH] add integration tests for filepart --- addons/addon-image/src/IIPHandler.ts | 8 ++- addons/addon-image/src/ImageAddon.ts | 7 +-- addons/addon-image/test/ImageAddon.test.ts | 61 ++++++++++++++++++++++ 3 files changed, 68 insertions(+), 8 deletions(-) diff --git a/addons/addon-image/src/IIPHandler.ts b/addons/addon-image/src/IIPHandler.ts index 7cacb88a0..249a89f3c 100644 --- a/addons/addon-image/src/IIPHandler.ts +++ b/addons/addon-image/src/IIPHandler.ts @@ -55,7 +55,11 @@ export class IIPHandler implements IOscHandler, IResetHandler { this._qoiDec = new QoiDecoder(DecoderConst.KEEP_DATA); } - public reset(): void {} + public reset(): void { + this._hp.reset(); + this._dec.release(); + this._qoiDec.release(); + } public start(): void { this._aborted = false; @@ -124,7 +128,7 @@ export class IIPHandler implements IOscHandler, IResetHandler { } const scale = this._coreTerminal._core._coreBrowserService?.dpr ?? 1; const report = `\x1b]1337;ReportCellSize=${height.toFixed(3)};${width.toFixed(3)};${scale.toFixed(3)}\x1b\\`; - this._coreTerminal?._core.coreService.triggerDataEvent(report); + this._coreTerminal.input(report, false); return true; } diff --git a/addons/addon-image/src/ImageAddon.ts b/addons/addon-image/src/ImageAddon.ts index 7e0f29d3f..8fd395431 100644 --- a/addons/addon-image/src/ImageAddon.ts +++ b/addons/addon-image/src/ImageAddon.ts @@ -137,11 +137,6 @@ export class ImageAddon implements ITerminalAddon, IImageApi { // enable size reports if (this._opts.enableSizeReports) { - // const windowOptions = terminal.getOption('windowOptions'); - // windowOptions.getWinSizePixels = true; - // windowOptions.getCellSizePixels = true; - // windowOptions.getWinSizeChars = true; - // terminal.setOption('windowOptions', windowOptions); const windowOps = terminal.options.windowOptions ?? {}; windowOps.getWinSizePixels = true; windowOps.getCellSizePixels = true; @@ -260,7 +255,7 @@ export class ImageAddon implements ITerminalAddon, IImageApi { } private _report(s: string): void { - this._terminal?._core.coreService.triggerDataEvent(s); + this._terminal?._core.input(s, false); } private _decset(params: (number | number[])[]): boolean { diff --git a/addons/addon-image/test/ImageAddon.test.ts b/addons/addon-image/test/ImageAddon.test.ts index dc729ec63..f3cde06a8 100644 --- a/addons/addon-image/test/ImageAddon.test.ts +++ b/addons/addon-image/test/ImageAddon.test.ts @@ -290,6 +290,67 @@ test.describe('ImageAddon', () => { }); }); + test.describe('IIP support', () => { + test('size params is optional/informative', async () => { + // too small size param + await ctx.proxy.write(`\x1b]1337;File=inline=1;size=5:${PALETTE_PNG_BASE64}\x07`); + deepStrictEqual(await getOrigSize(1), [640, 80]); + // no size aparm at all + await ctx.proxy.write(`\x1b[10H\x1b]1337;File=inline=1:${PALETTE_QOI_BASE64}\x07`); + deepStrictEqual(await getOrigSize(2), [640, 80]); + }); + test.skip('FilePart support - bytewise', async () => { + // opener + await ctx.proxy.write(`\x1b]1337;MultipartFile=inline=1\x07`); + // byte-wise + for (let i = 0; i < PALETTE_PNG_BASE64.length; ++i) { + await ctx.proxy.write(`\x1b]1337;FilePart=${PALETTE_PNG_BASE64[i]}\x07`); + } + // finalizer + await ctx.proxy.write(`\x1b]1337;FileEnd\x07`); + deepStrictEqual(await getOrigSize(1), [640, 80]); + }); + test('FilePart support - chunks', async () => { + // opener + await ctx.proxy.write(`\x1b]1337;MultipartFile=inline=1\x07`); + // chunks + for (let i = 0; i < PALETTE_PNG_BASE64.length; i += 256) { + await ctx.proxy.write(`\x1b]1337;FilePart=${PALETTE_PNG_BASE64.slice(i, i + 256)}\x07`); + } + // finalizer + await ctx.proxy.write(`\x1b]1337;FileEnd\x07`); + deepStrictEqual(await getOrigSize(1), [640, 80]); + }); + test('FilePart support - edgecases', async () => { + // multiple opener do not harm + for (let i = 0; i < 10; ++i) { + await ctx.proxy.write(`\x1b]1337;MultipartFile=inline=1\x07`); + } + // multiple finalizer do not harm + for (let i = 0; i < 5; ++i) { + await ctx.proxy.write(`\x1b]1337;FileEnd\x07`); + } + // chunks w'o opener are ignored + for (let i = 0; i < PALETTE_PNG_BASE64.length; i += 256) { + await ctx.proxy.write(`\x1b]1337;FilePart=${PALETTE_PNG_BASE64.slice(i, i + 256)}\x07`); + } + await ctx.proxy.write(`\x1b]1337;FileEnd\x07`); + pollFor(ctx.page, 'window.imageAddon._storage._images.size', 0); + }); + test('FilePart support - other IIP sequence cancels chunked image', async () => { + // opener + await ctx.proxy.write(`\x1b]1337;MultipartFile=inline=1\x07`); + // chunks + for (let i = 0; i < PALETTE_PNG_BASE64.length; i += 256) { + await ctx.proxy.write(`\x1b]1337;FilePart=${PALETTE_PNG_BASE64.slice(i, i + 256)}\x07`); + } + // finalizer skipped + // write spinfox.png + await ctx.proxy.write(TESTDATA_IIP[1][0]); + deepStrictEqual(await getOrigSize(1), TESTDATA_IIP[1][1]); + }); + }); + test.describe('IIP support - testimages', () => { test('palette.png', async () => { await ctx.proxy.write(TESTDATA_IIP[0][0]);