evOo-local/apps/web/src/lib/csv-preview.test.ts
cynarAI e28c3acf02
feat: let the pane beside a conversation follow the bot's work (#123)
The live screen opens wide beside the chat while the bot works on it or asks
for a takeover, a file the bot presents as its result opens next to the
conversation, and a question that scrolled away gets a "Needs you" pill back
to it. Shared core rules derive the focus from signals clients already have
(pointer events, takeover requests, a new `present` flag on attach_file,
pending asks), move the pane only on focus edges, never replace a pane the
user opened, and learn per bot whether the screen opens on its own. Pane
widths persist per device; mobile shows a pill that opens the computer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C7VSRHHzyt2KwoCkUkZ2Gc
2026-10-03 22:23:46 +02:00

32 lines
956 B
TypeScript

import { describe, expect, it } from "vitest";
import { parseCsvPreview } from "./csv-preview";
describe("parseCsvPreview", () => {
it("reads quoted fields, doubled quotes and CRLF rows", () => {
expect(parseCsvPreview('name,note\r\n"Smith, Ann","said ""hi"""\r\nBo,\n')).toEqual({
rows: [
["name", "note"],
["Smith, Ann", 'said "hi"'],
["Bo", ""],
],
truncated: false,
});
});
it("keeps a final row without a trailing newline and skips blank lines", () => {
expect(parseCsvPreview("a,b\n\n1,2").rows).toEqual([
["a", "b"],
["1", "2"],
]);
});
it("keeps newlines inside quoted fields", () => {
expect(parseCsvPreview('a\n"line 1\nline 2"').rows).toEqual([["a"], ["line 1\nline 2"]]);
});
it("stops after the row limit", () => {
const result = parseCsvPreview("1\n2\n3\n4\n", 2);
expect(result).toEqual({ rows: [["1"], ["2"]], truncated: true });
});
});