1import { describe, expect, it } from "vitest"; 2import { parseCsv } from "../csv-parser.js"; 3 4describe("parseCsv (RFC 4180, T-165)", () => { 5 it("parses a plain row", () => { 6 expect(parseCsv("a,b,c")).toEqual([["a", "b", "c"]]); 7 }); 8 9 it("splits rows on LF, CRLF and CR", () => { 10 expect(parseCsv("a\nb\r\nc\rd")).toEqual([["a"], ["b"], ["c"], ["d"]]); 11 }); 12 13 it("handles quoted fields with commas and escaped quotes", () => { 14 expect(parseCsv('a,"x, y","say ""hi""",b')).toEqual([["a", "x, y", 'say "hi"', "b"]]); 15 }); 16 17 it("handles newlines inside quotes", () => { 18 expect(parseCsv('a,"line1\nline2",b')).toEqual([["a", "line1\nline2", "b"]]); 19 }); 20 21 it("strips a UTF-8 BOM", () => { 22 expect(parseCsv("a,b")).toEqual([["a", "b"]]); 23 }); 24 25 it("tolerates ragged rows (extras kept; the caller pads short rows)", () => { 26 expect(parseCsv("a,b,c\n1\n1,2,3,4")).toEqual([["a", "b", "c"], ["1"], ["1", "2", "3", "4"]]); 27 }); 28 29 it("keeps an unterminated quote's collected content", () => { 30 expect(parseCsv('a,"unterminated,b')).toEqual([["a", "unterminated,b"]]); 31 }); 32 33 it("empty input has no rows", () => { 34 expect(parseCsv("")).toEqual([]); 35 }); 36 37 it("a trailing empty line does not create a phantom row", () => { 38 expect(parseCsv("a,b\n1,2\n")).toEqual([["a", "b"], ["1", "2"]]); 39 }); 40}); 41