mirror of
https://github.com/badlogic/pi-mono.git
synced 2026-11-05 23:37:25 +00:00
fix(coding-agent): report the real size of an oversized last line in the bash truncation notice
fixes #10015
This commit is contained in:
parent
d9af3d73af
commit
e33e2abc88
2 changed files with 50 additions and 1 deletions
|
|
@ -48,6 +48,7 @@ export class OutputAccumulator {
|
|||
private completedLines = 0;
|
||||
private totalLines = 0;
|
||||
private currentLineBytes = 0;
|
||||
private lastCompletedLineBytes = 0;
|
||||
private hasOpenLine = false;
|
||||
private finished = false;
|
||||
|
||||
|
|
@ -175,8 +176,9 @@ export class OutputAccumulator {
|
|||
}
|
||||
}
|
||||
|
||||
/** Bytes of the last line: the open one, or the one the last newline closed. */
|
||||
getLastLineBytes(): number {
|
||||
return this.currentLineBytes;
|
||||
return this.hasOpenLine ? this.currentLineBytes : this.lastCompletedLineBytes;
|
||||
}
|
||||
|
||||
private appendDecodedText(text: string): void {
|
||||
|
|
@ -194,8 +196,10 @@ export class OutputAccumulator {
|
|||
|
||||
let newlines = 0;
|
||||
let lastNewline = -1;
|
||||
let previousNewline = -1;
|
||||
for (let i = text.indexOf("\n"); i !== -1; i = text.indexOf("\n", i + 1)) {
|
||||
newlines++;
|
||||
previousNewline = lastNewline;
|
||||
lastNewline = i;
|
||||
}
|
||||
if (newlines === 0) {
|
||||
|
|
@ -203,6 +207,10 @@ export class OutputAccumulator {
|
|||
this.hasOpenLine = true;
|
||||
} else {
|
||||
this.completedLines += newlines;
|
||||
// The line the last newline closed began in an earlier chunk when no newline precedes it here.
|
||||
this.lastCompletedLineBytes =
|
||||
(previousNewline === -1 ? this.currentLineBytes : 0) +
|
||||
byteLength(text.slice(previousNewline + 1, lastNewline));
|
||||
const tail = text.slice(lastNewline + 1);
|
||||
this.currentLineBytes = byteLength(tail);
|
||||
this.hasOpenLine = tail.length > 0;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,41 @@
|
|||
import { rm } from "node:fs/promises";
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import { OutputAccumulator } from "../src/core/tools/output-accumulator.ts";
|
||||
|
||||
describe("OutputAccumulator last line size (#10015)", () => {
|
||||
const tempFiles: string[] = [];
|
||||
|
||||
afterEach(async () => {
|
||||
await Promise.all(tempFiles.splice(0).map((path) => rm(path, { force: true })));
|
||||
});
|
||||
|
||||
async function sizeOf(chunks: string[]): Promise<{ lastLineBytes: number; lastLinePartial: boolean }> {
|
||||
const output = new OutputAccumulator({ maxBytes: 1024 });
|
||||
for (const chunk of chunks) output.append(Buffer.from(chunk));
|
||||
output.finish();
|
||||
const snapshot = output.snapshot();
|
||||
await output.closeTempFile();
|
||||
if (snapshot.fullOutputPath) tempFiles.push(snapshot.fullOutputPath);
|
||||
return { lastLineBytes: output.getLastLineBytes(), lastLinePartial: snapshot.truncation.lastLinePartial };
|
||||
}
|
||||
|
||||
// #10015: a trailing newline reset the live line counter, so the notice reported the line as 0B.
|
||||
it("reports the size of an oversized last line that ends with a newline", async () => {
|
||||
expect(await sizeOf([`${"a".repeat(2000)}\n`])).toEqual({ lastLineBytes: 2000, lastLinePartial: true });
|
||||
});
|
||||
|
||||
it("reports the size of an oversized last line that is still open", async () => {
|
||||
expect(await sizeOf(["a".repeat(2000)])).toEqual({ lastLineBytes: 2000, lastLinePartial: true });
|
||||
});
|
||||
|
||||
it("sums a line split across chunks", async () => {
|
||||
expect(await sizeOf(["x\n", "a".repeat(1500), `${"a".repeat(500)}\n`])).toEqual({
|
||||
lastLineBytes: 2000,
|
||||
lastLinePartial: true,
|
||||
});
|
||||
});
|
||||
|
||||
it("measures only the last line when a chunk holds several", async () => {
|
||||
expect(await sizeOf([`short\n${"a".repeat(2000)}\n`])).toEqual({ lastLineBytes: 2000, lastLinePartial: true });
|
||||
});
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue