initial commit

This commit is contained in:
2025-08-20 09:40:45 -04:00
commit 10a8c54b70
18 changed files with 641 additions and 0 deletions

81
test/csv.spec.ts Normal file
View File

@@ -0,0 +1,81 @@
import { describe, it, expect } from "bun:test";
import { CsvParser, FileChunkSource } from "../src/index.ts";
describe("CsvParser - string input", () => {
it("parses simple CSV with headers to objects", async () => {
const parser = new CsvParser();
const csv = "name,age\nAlice,30\nBob,40";
const result = await parser.parseFromString(csv, { hasHeader: true, output: "object" });
expect(result.headers).toEqual(["name", "age"]);
expect(result.rows).toEqual([
{ name: "Alice", age: "30" },
{ name: "Bob", age: "40" },
]);
});
it("handles quoted fields with commas and escaped quotes", async () => {
const parser = new CsvParser();
const csv = [
'"name","note"',
'"Alice","He said ""hello"", world"',
'"Bob","x,y,z"',
].join("\n");
const result = await parser.parseFromString(csv, { hasHeader: true, output: "object" });
expect(result.rows).toEqual([
{ name: "Alice", note: 'He said "hello", world' },
{ name: "Bob", note: "x,y,z" },
]);
});
it("supports CRLF line endings", async () => {
const parser = new CsvParser();
const csv = "a,b\r\n1,2\r\n3,4";
const result = await parser.parseFromString(csv, { hasHeader: true });
expect(result.headers).toEqual(["a", "b"]);
expect(result.rows).toEqual([
["1", "2"],
["3", "4"],
]);
});
it("skips empty lines by default", async () => {
const parser = new CsvParser();
const csv = "a,b\n\n1,2\n\n";
const result = await parser.parseFromString(csv, { hasHeader: true });
expect(result.rows).toEqual([["1", "2"]]);
});
it("normalizes row length when validateRowLength is true (default)", async () => {
const parser = new CsvParser();
const csv = "a,b,c\n1,2\n3,4,5";
const result = await parser.parseFromString(csv, { hasHeader: true });
expect(result.rows).toEqual([
["1", "2", ""],
["3", "4", "5"],
]);
});
});
describe("CsvParser - file input", () => {
it("parses a CSV file via FileChunkSource", async () => {
const parser = new CsvParser();
const content = "city,temp\nBerlin,12\nMunich,10";
const tmpPath = `${process.cwd()}/test.__tmp.csv`;
await Bun.write(tmpPath, content);
try {
const source = new FileChunkSource(tmpPath);
const result = await parser.parseFromSource(source, { hasHeader: true, output: "object" });
expect(result.rows).toEqual([
{ city: "Berlin", temp: "12" },
{ city: "Munich", temp: "10" },
]);
} finally {
// best-effort cleanup
try { await Bun.write(tmpPath, ""); } catch {}
}
});
});