import { describe, it, expect } from "vitest"; import { parseCsv } from "../loader"; describe("parseCsv - basic parsing", () => { it("should parse a simple CSV with primitive types", () => { const csv = [ "name,age,active", "string,number,boolean", "Alice,30,true", "Bob,25,false", ].join("\n"); const result = parseCsv(csv, { emitTypes: false }); expect(result.data).toHaveLength(2); expect(result.data[0]).toEqual({ name: "Alice", age: 30, active: true }); expect(result.data[1]).toEqual({ name: "Bob", age: 25, active: false }); }); it("should parse CSV with int and float columns", () => { const csv = [ "id,count,price", "int,int,float", "1,5,9.99", "2,3,4.50", ].join("\n"); const result = parseCsv(csv, { emitTypes: false }); expect(result.data).toHaveLength(2); expect(result.data[0]).toEqual({ id: 1, count: 5, price: 9.99 }); expect(result.data[1]).toEqual({ id: 2, count: 3, price: 4.5 }); }); it("should parse CSV with non-ASCII characters and comments", () => { const csv = [ '# id: unique intent state ID (e.g. "仙人掌怪-boost")', "id", "string", "仙人掌怪-boost", "仙人掌怪-defend", "仙人掌怪-attack", ].join("\n"); const result = parseCsv(csv, { emitTypes: false }); expect(result.data).toHaveLength(3); expect(result.data[0]).toEqual({ id: "仙人掌怪-boost" }); expect(result.data[1]).toEqual({ id: "仙人掌怪-defend" }); expect(result.data[2]).toEqual({ id: "仙人掌怪-attack" }); }); it("should parse CSV with string literal columns (unquoted in CSV)", () => { const csv = [ "name,status", "string,'on' | 'off'", "Alice,on", "Bob,off", ].join("\n"); const result = parseCsv(csv, { emitTypes: false }); expect(result.data).toHaveLength(2); expect(result.data[0]).toEqual({ name: "Alice", status: "on" }); expect(result.data[1]).toEqual({ name: "Bob", status: "off" }); }); it("should parse CSV with array columns", () => { const csv = [ "name,tags", "string,string[]", "Alice,[dev; admin]", "Bob,[user]", ].join("\n"); const result = parseCsv(csv, { emitTypes: false }); expect(result.data).toHaveLength(2); expect(result.data[0]).toEqual({ name: "Alice", tags: ["dev", "admin"] }); expect(result.data[1]).toEqual({ name: "Bob", tags: ["user"] }); }); it("should parse CSV with tuple columns", () => { const csv = [ "name,coords", "string,[number; number]", "Alice,[1; 2]", "Bob,[3; 4]", ].join("\n"); const result = parseCsv(csv, { emitTypes: false }); expect(result.data).toHaveLength(2); expect(result.data[0]).toEqual({ name: "Alice", coords: [1, 2] }); expect(result.data[1]).toEqual({ name: "Bob", coords: [3, 4] }); }); it("should require at least 2 rows (header + schema)", () => { const csv = "name,age\nstring,number"; expect(() => parseCsv(csv, { emitTypes: false })).not.toThrow(); const csv1Row = "name,age"; expect(() => parseCsv(csv1Row, { emitTypes: false })).toThrow( "at least 2 rows", ); }); it("should throw if header and schema count mismatch", () => { const csv = "name,age\nstring"; expect(() => parseCsv(csv, { emitTypes: false })).toThrow("does not match"); }); });