convert-buddy-js 0.9.4 → 0.9.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/README.md +142 -5
  2. package/dist/src/browser.d.ts +74 -0
  3. package/dist/src/browser.js +140 -0
  4. package/dist/src/browser.js.map +1 -0
  5. package/dist/src/index.d.ts +22 -2
  6. package/dist/src/index.js +82 -8
  7. package/dist/src/index.js.map +1 -1
  8. package/dist/src/node.d.ts +83 -2
  9. package/dist/src/node.js +270 -2
  10. package/dist/src/node.js.map +1 -1
  11. package/dist/tests/edge-cases/control-features.test.d.ts +2 -0
  12. package/dist/tests/edge-cases/control-features.test.js +87 -0
  13. package/dist/tests/edge-cases/control-features.test.js.map +1 -0
  14. package/dist/tests/edge-cases/csv-edge-cases.test.d.ts +2 -0
  15. package/dist/tests/edge-cases/csv-edge-cases.test.js +547 -0
  16. package/dist/tests/edge-cases/csv-edge-cases.test.js.map +1 -0
  17. package/dist/tests/edge-cases/detection.test.d.ts +2 -0
  18. package/dist/tests/edge-cases/detection.test.js +129 -0
  19. package/dist/tests/edge-cases/detection.test.js.map +1 -0
  20. package/dist/tests/edge-cases/error-handling.test.d.ts +2 -0
  21. package/dist/tests/edge-cases/error-handling.test.js +448 -0
  22. package/dist/tests/edge-cases/error-handling.test.js.map +1 -0
  23. package/dist/tests/edge-cases/ndjson-edge-cases.test.d.ts +2 -0
  24. package/dist/tests/edge-cases/ndjson-edge-cases.test.js +539 -0
  25. package/dist/tests/edge-cases/ndjson-edge-cases.test.js.map +1 -0
  26. package/dist/tests/edge-cases/node-helpers.test.d.ts +2 -0
  27. package/dist/tests/edge-cases/node-helpers.test.js +114 -0
  28. package/dist/tests/edge-cases/node-helpers.test.js.map +1 -0
  29. package/dist/wasm/nodejs/convert_buddy_bg.wasm +0 -0
  30. package/dist/wasm/web/convert_buddy_bg.wasm +0 -0
  31. package/package.json +6 -2
@@ -0,0 +1,129 @@
1
+ import { describe, it } from "node:test";
2
+ import {
3
+ detectFormat,
4
+ detectCsvFieldsAndDelimiter
5
+ } from "../../src/index.js";
6
+ import { strict as assert } from "node:assert";
7
+ describe("CSV Format Detection", () => {
8
+ describe("Delimiter Detection", () => {
9
+ it("should detect comma-delimited CSV", async () => {
10
+ const csv = "name,age,city\nAlice,30,NYC\nBob,25,LA\n";
11
+ const detection = await detectCsvFieldsAndDelimiter(csv);
12
+ assert.strictEqual(detection?.delimiter, ",");
13
+ assert.strictEqual(detection?.fields.length, 3);
14
+ assert.deepStrictEqual(detection?.fields, ["name", "age", "city"]);
15
+ });
16
+ it("should detect tab-delimited CSV", async () => {
17
+ const csv = "name age city\nAlice 30 NYC\nBob 25 LA\n";
18
+ const detection = await detectCsvFieldsAndDelimiter(csv);
19
+ assert.strictEqual(detection?.delimiter, " ");
20
+ assert.strictEqual(detection?.fields.length, 3);
21
+ });
22
+ it("should detect semicolon-delimited CSV", async () => {
23
+ const csv = "name;age;city\nAlice;30;NYC\nBob;25;LA\n";
24
+ const detection = await detectCsvFieldsAndDelimiter(csv);
25
+ assert.strictEqual(detection?.delimiter, ";");
26
+ assert.strictEqual(detection?.fields.length, 3);
27
+ });
28
+ it("should detect pipe-delimited CSV", async () => {
29
+ const csv = "name|age|city\nAlice|30|NYC\nBob|25|LA\n";
30
+ const detection = await detectCsvFieldsAndDelimiter(csv);
31
+ assert.strictEqual(detection?.delimiter, "|");
32
+ assert.strictEqual(detection?.fields.length, 3);
33
+ assert.deepStrictEqual(detection?.fields, ["name", "age", "city"]);
34
+ });
35
+ it("should detect pipe delimiter with many columns", async () => {
36
+ const csv = "col_id|col_name|col_desc|col_category|col_type|col_url|col_price|col_discount\n001|product_a|content_a|category_a|type_a|http://example.com|100.00|80.00\n002|product_b|content_b|category_b|type_b|http://example.com|200.00|150.00\n";
37
+ const detection = await detectCsvFieldsAndDelimiter(csv);
38
+ assert.strictEqual(detection?.delimiter, "|");
39
+ assert.strictEqual(detection?.fields.length, 8);
40
+ assert.strictEqual(detection?.fields[0], "col_id");
41
+ assert.strictEqual(detection?.fields[7], "col_discount");
42
+ });
43
+ it("should prefer pipe delimiter when counts are close", async () => {
44
+ const csv = "a|b|c|d|e\n1|2|3|4|5\n,,,,,\n";
45
+ const detection = await detectCsvFieldsAndDelimiter(csv);
46
+ assert.strictEqual(detection?.delimiter, "|");
47
+ });
48
+ it("should detect delimiter correctly with quoted fields", async () => {
49
+ const csv = 'ProductID|Code|Name|Description\n"SKU123"|"CODE456"|"Item X"|"Contains | pipe"\n';
50
+ const detection = await detectCsvFieldsAndDelimiter(csv);
51
+ assert.strictEqual(detection?.delimiter, "|");
52
+ assert.strictEqual(detection?.fields.length, 4);
53
+ });
54
+ it("should handle Google Shopping feed format", async () => {
55
+ const csv = `col_1|col_2|col_3|col_4|col_5|col_6|col_7|col_8|col_9|col_10|col_11|col_12|col_13|col_14|col_15|col_16|col_17|col_18|col_19|col_20|col_21|col_22|col_23|col_24|col_25|col_26|col_27|col_28|col_29|col_30|col_31|col_32|col_33|col_34|col_35|col_36|col_37|col_38|col_39,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
56
+ row1_a|row1_b|row1_c|row1_d|row1_e|row1_f|row1_g|row1_h|row1_i|row1_j|row1_k|row1_l|row1_m|row1_n|row1_o|row1_p|row1_q|row1_r|row1_s|row1_t|row1_u|row1_v|row1_w|row1_x|row1_y|row1_z|row1_aa|row1_ab|row1_ac|row1_ad|row1_ae|row1_af|row1_ag|row1_ah|row1_ai|row1_aj|row1_ak|row1_al|row1_am|||||
57
+ row2_a|row2_b|row2_c|row2_d|row2_e|row2_f|row2_g|row2_h|row2_i|row2_j|row2_k|row2_l|row2_m|row2_n|row2_o|row2_p|row2_q|row2_r|row2_s|row2_t|row2_u|row2_v|row2_w|row2_x|row2_y|row2_z|row2_aa|row2_ab|row2_ac|row2_ad|row2_ae|row2_af|row2_ag|row2_ah|row2_ai|row2_aj|row2_ak|row2_al|row2_am|||||
58
+ `;
59
+ const detection = await detectCsvFieldsAndDelimiter(csv);
60
+ assert.strictEqual(detection?.delimiter, "|");
61
+ assert(detection.fields.length > 30);
62
+ assert.strictEqual(detection?.fields[0], "col_1");
63
+ assert.strictEqual(detection?.fields[1], "col_2");
64
+ });
65
+ });
66
+ describe("Format Detection", () => {
67
+ it("should detect JSON format", async () => {
68
+ const json = '{"name":"Alice","age":30}';
69
+ const format = await detectFormat(json);
70
+ assert.strictEqual(format, "json");
71
+ });
72
+ it("should detect NDJSON format", async () => {
73
+ const ndjson = '{"name":"Alice","age":30}\n{"name":"Bob","age":25}\n';
74
+ const format = await detectFormat(ndjson);
75
+ assert.strictEqual(format, "ndjson");
76
+ });
77
+ it("should detect XML format", async () => {
78
+ const xml = '<?xml version="1.0"?><root><item>test</item></root>';
79
+ const format = await detectFormat(xml);
80
+ assert.strictEqual(format, "xml");
81
+ });
82
+ });
83
+ describe("Edge Cases", () => {
84
+ it("should handle empty file", async () => {
85
+ const detection = await detectCsvFieldsAndDelimiter("");
86
+ assert.strictEqual(detection, null);
87
+ });
88
+ it("should handle single column", async () => {
89
+ const csv = "name\nAlice\nBob\n";
90
+ const detection = await detectCsvFieldsAndDelimiter(csv);
91
+ assert.strictEqual(detection?.fields.length, 1);
92
+ });
93
+ it("should handle CSV with Unicode characters", async () => {
94
+ const csv = "\u540D\u524D|\u5E74\u9F62|\u90FD\u5E02\n\u592A\u90CE|25|\u6771\u4EAC\n";
95
+ const detection = await detectCsvFieldsAndDelimiter(csv);
96
+ assert.strictEqual(detection?.delimiter, "|");
97
+ assert.deepStrictEqual(detection?.fields, ["\u540D\u524D", "\u5E74\u9F62", "\u90FD\u5E02"]);
98
+ });
99
+ it("should handle CSV with special characters in field names", async () => {
100
+ const csv = "product_id|unit-price|is_available\n123|19.99|true\n";
101
+ const detection = await detectCsvFieldsAndDelimiter(csv);
102
+ assert.strictEqual(detection?.delimiter, "|");
103
+ assert.deepStrictEqual(detection?.fields, [
104
+ "product_id",
105
+ "unit-price",
106
+ "is_available"
107
+ ]);
108
+ });
109
+ it("should handle large number of fields", async () => {
110
+ const fields = Array.from({ length: 100 }, (_, i) => `field${i + 1}`);
111
+ const data = fields.join("|") + "\n";
112
+ const detection = await detectCsvFieldsAndDelimiter(data);
113
+ assert.strictEqual(detection?.delimiter, "|");
114
+ assert.strictEqual(detection?.fields.length, 100);
115
+ });
116
+ it("should detect delimiter consistency across multiple lines", async () => {
117
+ const csv = "col1|col2|col3\nval1|val2|val3\nval4|val5|val6\nval7|val8|val9\n";
118
+ const detection = await detectCsvFieldsAndDelimiter(csv);
119
+ assert.strictEqual(detection?.delimiter, "|");
120
+ assert.strictEqual(detection?.fields.length, 3);
121
+ });
122
+ it("should handle mixed quoted and unquoted fields with pipe delimiter", async () => {
123
+ const csv = 'id|name|description\n1|"Product A"|Normal description\n2|"Product B"|"Description with | pipe"\n';
124
+ const detection = await detectCsvFieldsAndDelimiter(csv);
125
+ assert.strictEqual(detection?.delimiter, "|");
126
+ });
127
+ });
128
+ });
129
+ //# sourceMappingURL=detection.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../tests/edge-cases/detection.test.ts"],"sourcesContent":["import { describe, it } from \"node:test\";\r\nimport {\r\n detectFormat,\r\n detectCsvFieldsAndDelimiter,\r\n} from \"../../src/index.js\";\r\nimport { strict as assert } from \"node:assert\";\r\n\r\n/**\r\n * CSV Format Detection Test Suite\r\n * Tests the automatic detection of CSV delimiters and fields\r\n */\r\ndescribe(\"CSV Format Detection\", () => {\r\n describe(\"Delimiter Detection\", () => {\r\n it(\"should detect comma-delimited CSV\", async () => {\r\n const csv = \"name,age,city\\nAlice,30,NYC\\nBob,25,LA\\n\";\r\n const detection = await detectCsvFieldsAndDelimiter(csv);\r\n assert.strictEqual(detection?.delimiter, \",\");\r\n assert.strictEqual(detection?.fields.length, 3);\r\n assert.deepStrictEqual(detection?.fields, [\"name\", \"age\", \"city\"]);\r\n });\r\n\r\n it(\"should detect tab-delimited CSV\", async () => {\r\n const csv = \"name\\tage\\tcity\\nAlice\\t30\\tNYC\\nBob\\t25\\tLA\\n\";\r\n const detection = await detectCsvFieldsAndDelimiter(csv);\r\n assert.strictEqual(detection?.delimiter, \"\\t\");\r\n assert.strictEqual(detection?.fields.length, 3);\r\n });\r\n\r\n it(\"should detect semicolon-delimited CSV\", async () => {\r\n const csv = \"name;age;city\\nAlice;30;NYC\\nBob;25;LA\\n\";\r\n const detection = await detectCsvFieldsAndDelimiter(csv);\r\n assert.strictEqual(detection?.delimiter, \";\");\r\n assert.strictEqual(detection?.fields.length, 3);\r\n });\r\n\r\n it(\"should detect pipe-delimited CSV\", async () => {\r\n const csv = \"name|age|city\\nAlice|30|NYC\\nBob|25|LA\\n\";\r\n const detection = await detectCsvFieldsAndDelimiter(csv);\r\n assert.strictEqual(detection?.delimiter, \"|\");\r\n assert.strictEqual(detection?.fields.length, 3);\r\n assert.deepStrictEqual(detection?.fields, [\"name\", \"age\", \"city\"]);\r\n });\r\n\r\n it(\"should detect pipe delimiter with many columns\", async () => {\r\n const csv =\r\n \"col_id|col_name|col_desc|col_category|col_type|col_url|col_price|col_discount\\n001|product_a|content_a|category_a|type_a|http://example.com|100.00|80.00\\n002|product_b|content_b|category_b|type_b|http://example.com|200.00|150.00\\n\";\r\n const detection = await detectCsvFieldsAndDelimiter(csv);\r\n assert.strictEqual(detection?.delimiter, \"|\");\r\n assert.strictEqual(detection?.fields.length, 8);\r\n assert.strictEqual(detection?.fields[0], \"col_id\");\r\n assert.strictEqual(detection?.fields[7], \"col_discount\");\r\n });\r\n\r\n it(\"should prefer pipe delimiter when counts are close\", async () => {\r\n // This simulates a file with trailing empty comma-separated fields\r\n // that would confuse a naive delimiter detector\r\n const csv =\r\n \"a|b|c|d|e\\n1|2|3|4|5\\n,,,,,\\n\";\r\n const detection = await detectCsvFieldsAndDelimiter(csv);\r\n // Should detect pipe as the main delimiter used in the data\r\n assert.strictEqual(detection?.delimiter, \"|\");\r\n });\r\n\r\n it(\"should detect delimiter correctly with quoted fields\", async () => {\r\n const csv =\r\n 'ProductID|Code|Name|Description\\n\"SKU123\"|\"CODE456\"|\"Item X\"|\"Contains | pipe\"\\n';\r\n const detection = await detectCsvFieldsAndDelimiter(csv);\r\n assert.strictEqual(detection?.delimiter, \"|\");\r\n assert.strictEqual(detection?.fields.length, 4);\r\n });\r\n\r\n it(\"should handle Google Shopping feed format\", async () => {\r\n // Generic pipe-delimited format with many columns and trailing empty fields\r\n // This tests detection accuracy with realistic data volume\r\n const csv = `col_1|col_2|col_3|col_4|col_5|col_6|col_7|col_8|col_9|col_10|col_11|col_12|col_13|col_14|col_15|col_16|col_17|col_18|col_19|col_20|col_21|col_22|col_23|col_24|col_25|col_26|col_27|col_28|col_29|col_30|col_31|col_32|col_33|col_34|col_35|col_36|col_37|col_38|col_39,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\r\nrow1_a|row1_b|row1_c|row1_d|row1_e|row1_f|row1_g|row1_h|row1_i|row1_j|row1_k|row1_l|row1_m|row1_n|row1_o|row1_p|row1_q|row1_r|row1_s|row1_t|row1_u|row1_v|row1_w|row1_x|row1_y|row1_z|row1_aa|row1_ab|row1_ac|row1_ad|row1_ae|row1_af|row1_ag|row1_ah|row1_ai|row1_aj|row1_ak|row1_al|row1_am|||||\r\nrow2_a|row2_b|row2_c|row2_d|row2_e|row2_f|row2_g|row2_h|row2_i|row2_j|row2_k|row2_l|row2_m|row2_n|row2_o|row2_p|row2_q|row2_r|row2_s|row2_t|row2_u|row2_v|row2_w|row2_x|row2_y|row2_z|row2_aa|row2_ab|row2_ac|row2_ad|row2_ae|row2_af|row2_ag|row2_ah|row2_ai|row2_aj|row2_ak|row2_al|row2_am|||||\r\n`;\r\n const detection = await detectCsvFieldsAndDelimiter(csv);\r\n assert.strictEqual(detection?.delimiter, \"|\");\r\n // Should have detected the correct field count from the header\r\n assert(detection!.fields.length > 30);\r\n assert.strictEqual(detection?.fields[0], \"col_1\");\r\n assert.strictEqual(detection?.fields[1], \"col_2\");\r\n });\r\n });\r\n\r\n describe(\"Format Detection\", () => {\r\n it(\"should detect JSON format\", async () => {\r\n const json = '{\"name\":\"Alice\",\"age\":30}';\r\n const format = await detectFormat(json);\r\n assert.strictEqual(format, \"json\");\r\n });\r\n\r\n it(\"should detect NDJSON format\", async () => {\r\n const ndjson = '{\"name\":\"Alice\",\"age\":30}\\n{\"name\":\"Bob\",\"age\":25}\\n';\r\n const format = await detectFormat(ndjson);\r\n assert.strictEqual(format, \"ndjson\");\r\n });\r\n\r\n it(\"should detect XML format\", async () => {\r\n const xml =\r\n \"<?xml version=\\\"1.0\\\"?><root><item>test</item></root>\";\r\n const format = await detectFormat(xml);\r\n assert.strictEqual(format, \"xml\");\r\n });\r\n });\r\n\r\n describe(\"Edge Cases\", () => {\r\n it(\"should handle empty file\", async () => {\r\n const detection = await detectCsvFieldsAndDelimiter(\"\");\r\n assert.strictEqual(detection, null);\r\n });\r\n\r\n it(\"should handle single column\", async () => {\r\n const csv = \"name\\nAlice\\nBob\\n\";\r\n const detection = await detectCsvFieldsAndDelimiter(csv);\r\n assert.strictEqual(detection?.fields.length, 1);\r\n });\r\n\r\n it(\"should handle CSV with Unicode characters\", async () => {\r\n const csv = \"名前|年齢|都市\\n太郎|25|東京\\n\";\r\n const detection = await detectCsvFieldsAndDelimiter(csv);\r\n assert.strictEqual(detection?.delimiter, \"|\");\r\n assert.deepStrictEqual(detection?.fields, [\"名前\", \"年齢\", \"都市\"]);\r\n });\r\n\r\n it(\"should handle CSV with special characters in field names\", async () => {\r\n const csv = \"product_id|unit-price|is_available\\n123|19.99|true\\n\";\r\n const detection = await detectCsvFieldsAndDelimiter(csv);\r\n assert.strictEqual(detection?.delimiter, \"|\");\r\n assert.deepStrictEqual(detection?.fields, [\r\n \"product_id\",\r\n \"unit-price\",\r\n \"is_available\",\r\n ]);\r\n });\r\n\r\n it(\"should handle large number of fields\", async () => {\r\n // Create a CSV with 100 pipe-delimited fields\r\n const fields = Array.from({ length: 100 }, (_, i) => `field${i + 1}`);\r\n const data = fields.join(\"|\") + \"\\n\";\r\n const detection = await detectCsvFieldsAndDelimiter(data);\r\n assert.strictEqual(detection?.delimiter, \"|\");\r\n assert.strictEqual(detection?.fields.length, 100);\r\n });\r\n\r\n it(\"should detect delimiter consistency across multiple lines\", async () => {\r\n const csv =\r\n \"col1|col2|col3\\nval1|val2|val3\\nval4|val5|val6\\nval7|val8|val9\\n\";\r\n const detection = await detectCsvFieldsAndDelimiter(csv);\r\n assert.strictEqual(detection?.delimiter, \"|\");\r\n assert.strictEqual(detection?.fields.length, 3);\r\n });\r\n\r\n it(\"should handle mixed quoted and unquoted fields with pipe delimiter\", async () => {\r\n const csv =\r\n 'id|name|description\\n1|\"Product A\"|Normal description\\n2|\"Product B\"|\"Description with | pipe\"\\n';\r\n const detection = await detectCsvFieldsAndDelimiter(csv);\r\n assert.strictEqual(detection?.delimiter, \"|\");\r\n });\r\n });\r\n});\r\n"],"mappings":"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","names":[]}
@@ -0,0 +1,2 @@
1
+
2
+ export { }
@@ -0,0 +1,448 @@
1
+ import { describe, it } from "node:test";
2
+ import { convertToString, convert, ConvertBuddy } from "../../src/index.js";
3
+ import { strict as assert } from "node:assert";
4
+ describe("Error Handling - Comprehensive Safety Tests", () => {
5
+ describe("Input Errors", () => {
6
+ it("should handle invalid format specification", async () => {
7
+ try {
8
+ await convertToString("test", {
9
+ inputFormat: "invalid",
10
+ outputFormat: "json"
11
+ });
12
+ assert.fail("Should have thrown an error");
13
+ } catch (error) {
14
+ assert.ok(error);
15
+ }
16
+ });
17
+ it("should handle mismatched format (CSV data with JSON format)", async () => {
18
+ const csvData = "name,age\nAlice,30";
19
+ try {
20
+ await convertToString(csvData, {
21
+ inputFormat: "json",
22
+ outputFormat: "ndjson"
23
+ });
24
+ assert.ok(true);
25
+ } catch (error) {
26
+ assert.ok(error);
27
+ }
28
+ });
29
+ it("should handle corrupted CSV data", async () => {
30
+ const corruptedCsv = 'name,age\n"Alice,30\nBob,"25';
31
+ try {
32
+ await convertToString(corruptedCsv, {
33
+ inputFormat: "csv",
34
+ outputFormat: "ndjson"
35
+ });
36
+ assert.ok(true);
37
+ } catch (error) {
38
+ assert.ok(error);
39
+ }
40
+ });
41
+ it("should handle corrupted JSON data", async () => {
42
+ const corruptedJson = '{"name":"Alice","age":30';
43
+ try {
44
+ await convertToString(corruptedJson, {
45
+ inputFormat: "json",
46
+ outputFormat: "ndjson"
47
+ });
48
+ assert.ok(true);
49
+ } catch (error) {
50
+ assert.ok(error);
51
+ }
52
+ });
53
+ it("should handle truncated files", async () => {
54
+ const truncated = "name,age\nAlice,30\nBob,";
55
+ try {
56
+ const result = await convertToString(truncated, {
57
+ inputFormat: "csv",
58
+ outputFormat: "ndjson"
59
+ });
60
+ assert.ok(true);
61
+ } catch (error) {
62
+ assert.ok(error);
63
+ }
64
+ });
65
+ it("should handle binary data in text formats", async () => {
66
+ const binaryData = new Uint8Array([255, 254, 253, 252, 0, 1]);
67
+ try {
68
+ await convert(binaryData, {
69
+ inputFormat: "csv",
70
+ outputFormat: "ndjson"
71
+ });
72
+ assert.ok(true);
73
+ } catch (error) {
74
+ assert.ok(error);
75
+ }
76
+ });
77
+ });
78
+ describe("Encoding Errors", () => {
79
+ it("should handle invalid UTF-8 sequences", async () => {
80
+ const invalidUtf8 = new Uint8Array([255, 254, 253]);
81
+ try {
82
+ await convert(invalidUtf8, {
83
+ inputFormat: "csv",
84
+ outputFormat: "ndjson"
85
+ });
86
+ assert.ok(true);
87
+ } catch (error) {
88
+ assert.ok(error);
89
+ }
90
+ });
91
+ it("should handle UTF-8 BOM (Byte Order Mark)", async () => {
92
+ const bom = new Uint8Array([239, 187, 191]);
93
+ const csvData = new TextEncoder().encode("name,age\nAlice,30");
94
+ const withBom = new Uint8Array(bom.length + csvData.length);
95
+ withBom.set(bom, 0);
96
+ withBom.set(csvData, bom.length);
97
+ try {
98
+ const result = await convert(withBom, {
99
+ inputFormat: "csv",
100
+ outputFormat: "ndjson"
101
+ });
102
+ assert.ok(result);
103
+ } catch (error) {
104
+ assert.ok(error);
105
+ }
106
+ });
107
+ it("should handle null bytes in strings", async () => {
108
+ const csvWithNull = "name,value\nAlice,test\0null\nBob,normal";
109
+ try {
110
+ const result = await convertToString(csvWithNull, {
111
+ inputFormat: "csv",
112
+ outputFormat: "ndjson"
113
+ });
114
+ assert.ok(result);
115
+ } catch (error) {
116
+ assert.ok(error);
117
+ }
118
+ });
119
+ it("should handle incomplete multi-byte UTF-8 characters", async () => {
120
+ const incomplete = new Uint8Array([195]);
121
+ try {
122
+ await convert(incomplete, {
123
+ inputFormat: "csv",
124
+ outputFormat: "ndjson"
125
+ });
126
+ assert.ok(true);
127
+ } catch (error) {
128
+ assert.ok(error);
129
+ }
130
+ });
131
+ });
132
+ describe("Configuration Errors", () => {
133
+ it("should handle invalid delimiter characters", async () => {
134
+ try {
135
+ await convertToString("test", {
136
+ inputFormat: "csv",
137
+ outputFormat: "ndjson",
138
+ csvConfig: {
139
+ delimiter: ""
140
+ // Invalid empty delimiter
141
+ }
142
+ });
143
+ assert.ok(true);
144
+ } catch (error) {
145
+ assert.ok(error);
146
+ }
147
+ });
148
+ it("should handle invalid format combinations", async () => {
149
+ try {
150
+ await convertToString("test", {
151
+ inputFormat: "xml",
152
+ outputFormat: "csv"
153
+ // May not be supported
154
+ });
155
+ assert.ok(true);
156
+ } catch (error) {
157
+ assert.ok(error);
158
+ }
159
+ });
160
+ it("should handle conflicting options", async () => {
161
+ try {
162
+ await convertToString("test", {
163
+ inputFormat: "csv",
164
+ outputFormat: "ndjson",
165
+ csvConfig: {
166
+ hasHeaders: false
167
+ }
168
+ // Conflicting with no headers
169
+ });
170
+ assert.ok(true);
171
+ } catch (error) {
172
+ assert.ok(error);
173
+ }
174
+ });
175
+ });
176
+ describe("Resource Errors", () => {
177
+ it("should handle very large input (memory pressure)", async () => {
178
+ const largeSize = 100 * 1024 * 1024;
179
+ const chunkSize = 1024 * 1024;
180
+ let csv = "name,age\n";
181
+ for (let i = 0; i < Math.min(1e4, largeSize / 20); i++) {
182
+ csv += `Alice${i},${i}
183
+ `;
184
+ }
185
+ try {
186
+ const result = await convertToString(csv, {
187
+ inputFormat: "csv",
188
+ outputFormat: "ndjson"
189
+ });
190
+ assert.ok(result);
191
+ } catch (error) {
192
+ assert.ok(error);
193
+ }
194
+ });
195
+ it("should handle deeply nested recursion (stack overflow protection)", async () => {
196
+ let nested = { value: "deep" };
197
+ for (let i = 0; i < 1e3; i++) {
198
+ nested = { level: i, nested };
199
+ }
200
+ const ndjson = JSON.stringify(nested);
201
+ try {
202
+ const result = await convertToString(ndjson, {
203
+ inputFormat: "ndjson",
204
+ outputFormat: "json"
205
+ });
206
+ assert.ok(result);
207
+ } catch (error) {
208
+ assert.ok(error);
209
+ }
210
+ });
211
+ it("should handle rapid successive conversions (resource cleanup)", async () => {
212
+ const csv = "name,age\nAlice,30\nBob,25";
213
+ const promises = [];
214
+ for (let i = 0; i < 100; i++) {
215
+ promises.push(
216
+ convertToString(csv, {
217
+ inputFormat: "csv",
218
+ outputFormat: "ndjson"
219
+ })
220
+ );
221
+ }
222
+ try {
223
+ const results = await Promise.all(promises);
224
+ assert.strictEqual(results.length, 100);
225
+ } catch (error) {
226
+ assert.ok(error);
227
+ }
228
+ });
229
+ });
230
+ describe("Streaming Errors", () => {
231
+ it("should handle push after finish", async () => {
232
+ const buddy = await ConvertBuddy.create({
233
+ inputFormat: "csv",
234
+ outputFormat: "ndjson"
235
+ });
236
+ const data = new TextEncoder().encode("name,age\nAlice,30\n");
237
+ buddy.push(data);
238
+ buddy.finish();
239
+ try {
240
+ buddy.push(data);
241
+ assert.ok(true);
242
+ } catch (error) {
243
+ assert.ok(error);
244
+ }
245
+ });
246
+ it("should handle multiple finish calls", async () => {
247
+ const buddy = await ConvertBuddy.create({
248
+ inputFormat: "csv",
249
+ outputFormat: "ndjson"
250
+ });
251
+ const data = new TextEncoder().encode("name,age\nAlice,30\n");
252
+ buddy.push(data);
253
+ buddy.finish();
254
+ try {
255
+ buddy.finish();
256
+ assert.ok(true);
257
+ } catch (error) {
258
+ assert.ok(error);
259
+ }
260
+ });
261
+ it("should handle empty push", async () => {
262
+ const buddy = await ConvertBuddy.create({
263
+ inputFormat: "csv",
264
+ outputFormat: "ndjson"
265
+ });
266
+ try {
267
+ const empty = new Uint8Array(0);
268
+ buddy.push(empty);
269
+ assert.ok(true);
270
+ } catch (error) {
271
+ assert.ok(error);
272
+ }
273
+ });
274
+ it("should handle finish without any push", async () => {
275
+ const buddy = await ConvertBuddy.create({
276
+ inputFormat: "csv",
277
+ outputFormat: "ndjson"
278
+ });
279
+ try {
280
+ const result = buddy.finish();
281
+ assert.ok(result);
282
+ } catch (error) {
283
+ assert.ok(error);
284
+ }
285
+ });
286
+ });
287
+ describe("Error Recovery", () => {
288
+ it("should continue processing after recoverable errors", async () => {
289
+ const ndjson = `{"valid":1}
290
+ {invalid}
291
+ {"valid":2}`;
292
+ try {
293
+ const result = await convertToString(ndjson, {
294
+ inputFormat: "ndjson",
295
+ outputFormat: "json"
296
+ });
297
+ assert.ok(true);
298
+ } catch (error) {
299
+ assert.ok(error);
300
+ }
301
+ });
302
+ it("should provide meaningful error messages", async () => {
303
+ const invalidJson = "{invalid json}";
304
+ try {
305
+ await convertToString(invalidJson, {
306
+ inputFormat: "json",
307
+ outputFormat: "ndjson"
308
+ });
309
+ assert.fail("Should have thrown an error");
310
+ } catch (error) {
311
+ assert.ok(error.message);
312
+ assert.ok(error.message.length > 0);
313
+ }
314
+ });
315
+ it("should handle conversion after previous error", async () => {
316
+ try {
317
+ await convertToString("{invalid}", {
318
+ inputFormat: "json",
319
+ outputFormat: "ndjson"
320
+ });
321
+ } catch (error) {
322
+ }
323
+ const result = await convertToString('{"valid":true}', {
324
+ inputFormat: "json",
325
+ outputFormat: "ndjson"
326
+ });
327
+ assert.ok(result);
328
+ });
329
+ });
330
+ describe("Edge Case Combinations", () => {
331
+ it("should handle empty input with invalid format", async () => {
332
+ try {
333
+ await convertToString("", {
334
+ inputFormat: "invalid",
335
+ outputFormat: "json"
336
+ });
337
+ assert.ok(true);
338
+ } catch (error) {
339
+ assert.ok(error);
340
+ }
341
+ });
342
+ it("should handle corrupted data with streaming API", async () => {
343
+ const buddy = await ConvertBuddy.create({
344
+ inputFormat: "csv",
345
+ outputFormat: "ndjson"
346
+ });
347
+ try {
348
+ const corrupted = new TextEncoder().encode('name,age\n"Alice,30');
349
+ buddy.push(corrupted);
350
+ buddy.finish();
351
+ assert.ok(true);
352
+ } catch (error) {
353
+ assert.ok(error);
354
+ }
355
+ });
356
+ it("should handle Unicode errors in large files", async () => {
357
+ let data = "name,age\n";
358
+ for (let i = 0; i < 1e3; i++) {
359
+ data += `Alice${i},${i}
360
+ `;
361
+ }
362
+ const encoded = new TextEncoder().encode(data);
363
+ const corrupted = new Uint8Array(encoded);
364
+ corrupted[encoded.length / 2] = 255;
365
+ try {
366
+ await convert(corrupted, {
367
+ inputFormat: "csv",
368
+ outputFormat: "ndjson"
369
+ });
370
+ assert.ok(true);
371
+ } catch (error) {
372
+ assert.ok(error);
373
+ }
374
+ });
375
+ });
376
+ describe("Safety Guarantees", () => {
377
+ it("should never crash on any input", async () => {
378
+ const randomData = new Uint8Array(1e3);
379
+ for (let i = 0; i < randomData.length; i++) {
380
+ randomData[i] = Math.floor(Math.random() * 256);
381
+ }
382
+ try {
383
+ await convert(randomData, {
384
+ inputFormat: "csv",
385
+ outputFormat: "ndjson"
386
+ });
387
+ assert.ok(true);
388
+ } catch (error) {
389
+ assert.ok(error);
390
+ }
391
+ });
392
+ it("should handle all printable ASCII characters", async () => {
393
+ let csv = "name,value\n";
394
+ for (let i = 32; i < 127; i++) {
395
+ csv += `char${i},${String.fromCharCode(i)}
396
+ `;
397
+ }
398
+ try {
399
+ const result = await convertToString(csv, {
400
+ inputFormat: "csv",
401
+ outputFormat: "ndjson"
402
+ });
403
+ assert.ok(result);
404
+ } catch (error) {
405
+ assert.ok(error);
406
+ }
407
+ });
408
+ it("should handle all control characters", async () => {
409
+ let csv = "name,value\n";
410
+ for (let i = 0; i < 32; i++) {
411
+ if (i !== 10 && i !== 13) {
412
+ csv += `char${i},${String.fromCharCode(i)}
413
+ `;
414
+ }
415
+ }
416
+ try {
417
+ const result = await convertToString(csv, {
418
+ inputFormat: "csv",
419
+ outputFormat: "ndjson"
420
+ });
421
+ assert.ok(result);
422
+ } catch (error) {
423
+ assert.ok(error);
424
+ }
425
+ });
426
+ it("should never leak memory on errors", async () => {
427
+ const initialMem = process.memoryUsage().heapUsed;
428
+ for (let i = 0; i < 100; i++) {
429
+ try {
430
+ await convertToString("{invalid}", {
431
+ inputFormat: "json",
432
+ outputFormat: "ndjson"
433
+ });
434
+ } catch (error) {
435
+ }
436
+ }
437
+ if (global.gc) {
438
+ global.gc();
439
+ }
440
+ const finalMem = process.memoryUsage().heapUsed;
441
+ const memIncrease = (finalMem - initialMem) / (1024 * 1024);
442
+ assert.ok(memIncrease < 10, `Memory increased by ${memIncrease.toFixed(2)}MB`);
443
+ });
444
+ });
445
+ });
446
+ console.log("\u2713 Error Handling Test Suite loaded");
447
+ console.log(" Run with: node --test tests/edge-cases/error-handling.test.ts");
448
+ //# sourceMappingURL=error-handling.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../tests/edge-cases/error-handling.test.ts"],"sourcesContent":["import { describe, it } from \"node:test\";\r\nimport { convertToString, convert, ConvertBuddy } from \"../../src/index.js\";\r\nimport { strict as assert } from \"node:assert\";\r\n\r\n/**\r\n * Comprehensive Error Handling Test Suite\r\n * \r\n * Tests all possible error scenarios to ensure the code is safe and robust.\r\n * Every error condition that could occur should be tested here.\r\n */\r\n\r\ndescribe(\"Error Handling - Comprehensive Safety Tests\", () => {\r\n \r\n // ========== INPUT ERRORS ==========\r\n describe(\"Input Errors\", () => {\r\n it(\"should handle invalid format specification\", async () => {\r\n try {\r\n await convertToString(\"test\", {\r\n inputFormat: \"invalid\" as any,\r\n outputFormat: \"json\",\r\n });\r\n assert.fail(\"Should have thrown an error\");\r\n } catch (error: any) {\r\n assert.ok(error);\r\n }\r\n });\r\n\r\n it(\"should handle mismatched format (CSV data with JSON format)\", async () => {\r\n const csvData = \"name,age\\nAlice,30\";\r\n try {\r\n await convertToString(csvData, {\r\n inputFormat: \"json\",\r\n outputFormat: \"ndjson\",\r\n });\r\n // May succeed or fail depending on implementation\r\n assert.ok(true);\r\n } catch (error) {\r\n // Error is expected and acceptable\r\n assert.ok(error);\r\n }\r\n });\r\n\r\n it(\"should handle corrupted CSV data\", async () => {\r\n const corruptedCsv = \"name,age\\n\\\"Alice,30\\nBob,\\\"25\";\r\n try {\r\n await convertToString(corruptedCsv, {\r\n inputFormat: \"csv\",\r\n outputFormat: \"ndjson\",\r\n });\r\n assert.ok(true);\r\n } catch (error) {\r\n assert.ok(error);\r\n }\r\n });\r\n\r\n it(\"should handle corrupted JSON data\", async () => {\r\n const corruptedJson = '{\"name\":\"Alice\",\"age\":30';\r\n try {\r\n await convertToString(corruptedJson, {\r\n inputFormat: \"json\",\r\n outputFormat: \"ndjson\",\r\n });\r\n assert.ok(true);\r\n } catch (error) {\r\n assert.ok(error);\r\n }\r\n });\r\n\r\n it(\"should handle truncated files\", async () => {\r\n const truncated = \"name,age\\nAlice,30\\nBob,\";\r\n try {\r\n const result = await convertToString(truncated, {\r\n inputFormat: \"csv\",\r\n outputFormat: \"ndjson\",\r\n });\r\n // Truncated data may be handled gracefully\r\n assert.ok(true);\r\n } catch (error) {\r\n assert.ok(error);\r\n }\r\n });\r\n\r\n it(\"should handle binary data in text formats\", async () => {\r\n const binaryData = new Uint8Array([0xFF, 0xFE, 0xFD, 0xFC, 0x00, 0x01]);\r\n try {\r\n await convert(binaryData, {\r\n inputFormat: \"csv\",\r\n outputFormat: \"ndjson\",\r\n });\r\n assert.ok(true);\r\n } catch (error) {\r\n assert.ok(error);\r\n }\r\n });\r\n });\r\n\r\n // ========== ENCODING ERRORS ==========\r\n describe(\"Encoding Errors\", () => {\r\n it(\"should handle invalid UTF-8 sequences\", async () => {\r\n // Invalid UTF-8 sequence\r\n const invalidUtf8 = new Uint8Array([0xFF, 0xFE, 0xFD]);\r\n try {\r\n await convert(invalidUtf8, {\r\n inputFormat: \"csv\",\r\n outputFormat: \"ndjson\",\r\n });\r\n assert.ok(true);\r\n } catch (error) {\r\n assert.ok(error);\r\n }\r\n });\r\n\r\n it(\"should handle UTF-8 BOM (Byte Order Mark)\", async () => {\r\n const bom = new Uint8Array([0xEF, 0xBB, 0xBF]);\r\n const csvData = new TextEncoder().encode(\"name,age\\nAlice,30\");\r\n const withBom = new Uint8Array(bom.length + csvData.length);\r\n withBom.set(bom, 0);\r\n withBom.set(csvData, bom.length);\r\n\r\n try {\r\n const result = await convert(withBom, {\r\n inputFormat: \"csv\",\r\n outputFormat: \"ndjson\",\r\n });\r\n assert.ok(result);\r\n } catch (error) {\r\n assert.ok(error);\r\n }\r\n });\r\n\r\n it(\"should handle null bytes in strings\", async () => {\r\n const csvWithNull = \"name,value\\nAlice,test\\x00null\\nBob,normal\";\r\n try {\r\n const result = await convertToString(csvWithNull, {\r\n inputFormat: \"csv\",\r\n outputFormat: \"ndjson\",\r\n });\r\n assert.ok(result);\r\n } catch (error) {\r\n assert.ok(error);\r\n }\r\n });\r\n\r\n it(\"should handle incomplete multi-byte UTF-8 characters\", async () => {\r\n // Start of a multi-byte character without the rest\r\n const incomplete = new Uint8Array([0xC3]); // Start of 2-byte sequence\r\n try {\r\n await convert(incomplete, {\r\n inputFormat: \"csv\",\r\n outputFormat: \"ndjson\",\r\n });\r\n assert.ok(true);\r\n } catch (error) {\r\n assert.ok(error);\r\n }\r\n });\r\n });\r\n\r\n // ========== CONFIGURATION ERRORS ==========\r\n describe(\"Configuration Errors\", () => {\r\n it(\"should handle invalid delimiter characters\", async () => {\r\n try {\r\n await convertToString(\"test\", {\r\n inputFormat: \"csv\",\r\n outputFormat: \"ndjson\",\r\n csvConfig: {\r\n delimiter: \"\", // Invalid empty delimiter\r\n } as any,\r\n });\r\n assert.ok(true);\r\n } catch (error) {\r\n assert.ok(error);\r\n }\r\n });\r\n\r\n it(\"should handle invalid format combinations\", async () => {\r\n // Some format combinations might not be supported\r\n try {\r\n await convertToString(\"test\", {\r\n inputFormat: \"xml\",\r\n outputFormat: \"csv\" as any, // May not be supported\r\n });\r\n assert.ok(true);\r\n } catch (error) {\r\n assert.ok(error);\r\n }\r\n });\r\n\r\n it(\"should handle conflicting options\", async () => {\r\n try {\r\n await convertToString(\"test\", {\r\n inputFormat: \"csv\",\r\n outputFormat: \"ndjson\",\r\n csvConfig: {\r\n hasHeaders: false,\r\n },\r\n // Conflicting with no headers\r\n });\r\n assert.ok(true);\r\n } catch (error) {\r\n assert.ok(error);\r\n }\r\n });\r\n });\r\n\r\n // ========== RESOURCE ERRORS ==========\r\n describe(\"Resource Errors\", () => {\r\n it(\"should handle very large input (memory pressure)\", async () => {\r\n // Generate 100MB of CSV data\r\n const largeSize = 100 * 1024 * 1024;\r\n const chunkSize = 1024 * 1024;\r\n let csv = \"name,age\\n\";\r\n \r\n // Generate in chunks to avoid OOM during generation\r\n for (let i = 0; i < Math.min(10000, largeSize / 20); i++) {\r\n csv += `Alice${i},${i}\\n`;\r\n }\r\n\r\n try {\r\n const result = await convertToString(csv, {\r\n inputFormat: \"csv\",\r\n outputFormat: \"ndjson\",\r\n });\r\n assert.ok(result);\r\n } catch (error) {\r\n // OOM or timeout is acceptable for very large data\r\n assert.ok(error);\r\n }\r\n });\r\n\r\n it(\"should handle deeply nested recursion (stack overflow protection)\", async () => {\r\n // Create deeply nested JSON\r\n let nested: any = { value: \"deep\" };\r\n for (let i = 0; i < 1000; i++) {\r\n nested = { level: i, nested };\r\n }\r\n\r\n const ndjson = JSON.stringify(nested);\r\n\r\n try {\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n assert.ok(result);\r\n } catch (error) {\r\n // Stack overflow protection is acceptable\r\n assert.ok(error);\r\n }\r\n });\r\n\r\n it(\"should handle rapid successive conversions (resource cleanup)\", async () => {\r\n const csv = \"name,age\\nAlice,30\\nBob,25\";\r\n \r\n // Run 100 conversions rapidly\r\n const promises = [];\r\n for (let i = 0; i < 100; i++) {\r\n promises.push(\r\n convertToString(csv, {\r\n inputFormat: \"csv\",\r\n outputFormat: \"ndjson\",\r\n })\r\n );\r\n }\r\n\r\n try {\r\n const results = await Promise.all(promises);\r\n assert.strictEqual(results.length, 100);\r\n } catch (error) {\r\n assert.ok(error);\r\n }\r\n });\r\n });\r\n\r\n // ========== STREAMING ERRORS ==========\r\n describe(\"Streaming Errors\", () => {\r\n it(\"should handle push after finish\", async () => {\r\n const buddy = await ConvertBuddy.create({\r\n inputFormat: \"csv\",\r\n outputFormat: \"ndjson\",\r\n });\r\n\r\n const data = new TextEncoder().encode(\"name,age\\nAlice,30\\n\");\r\n buddy.push(data);\r\n buddy.finish();\r\n\r\n try {\r\n // Pushing after finish should be handled gracefully\r\n buddy.push(data);\r\n assert.ok(true);\r\n } catch (error) {\r\n assert.ok(error);\r\n }\r\n });\r\n\r\n it(\"should handle multiple finish calls\", async () => {\r\n const buddy = await ConvertBuddy.create({\r\n inputFormat: \"csv\",\r\n outputFormat: \"ndjson\",\r\n });\r\n\r\n const data = new TextEncoder().encode(\"name,age\\nAlice,30\\n\");\r\n buddy.push(data);\r\n buddy.finish();\r\n\r\n try {\r\n // Multiple finish calls should be handled gracefully\r\n buddy.finish();\r\n assert.ok(true);\r\n } catch (error) {\r\n assert.ok(error);\r\n }\r\n });\r\n\r\n it(\"should handle empty push\", async () => {\r\n const buddy = await ConvertBuddy.create({\r\n inputFormat: \"csv\",\r\n outputFormat: \"ndjson\",\r\n });\r\n\r\n try {\r\n const empty = new Uint8Array(0);\r\n buddy.push(empty);\r\n assert.ok(true);\r\n } catch (error) {\r\n assert.ok(error);\r\n }\r\n });\r\n\r\n it(\"should handle finish without any push\", async () => {\r\n const buddy = await ConvertBuddy.create({\r\n inputFormat: \"csv\",\r\n outputFormat: \"ndjson\",\r\n });\r\n\r\n try {\r\n const result = buddy.finish();\r\n assert.ok(result);\r\n } catch (error) {\r\n assert.ok(error);\r\n }\r\n });\r\n });\r\n\r\n // ========== ERROR RECOVERY ==========\r\n describe(\"Error Recovery\", () => {\r\n it(\"should continue processing after recoverable errors\", async () => {\r\n // Mix of valid and invalid JSON lines\r\n const ndjson = `{\"valid\":1}\\n{invalid}\\n{\"valid\":2}`;\r\n \r\n try {\r\n const result = await convertToString(ndjson, {\r\n inputFormat: \"ndjson\",\r\n outputFormat: \"json\",\r\n });\r\n // May skip invalid lines or fail entirely\r\n assert.ok(true);\r\n } catch (error) {\r\n assert.ok(error);\r\n }\r\n });\r\n\r\n it(\"should provide meaningful error messages\", async () => {\r\n const invalidJson = \"{invalid json}\";\r\n \r\n try {\r\n await convertToString(invalidJson, {\r\n inputFormat: \"json\",\r\n outputFormat: \"ndjson\",\r\n });\r\n assert.fail(\"Should have thrown an error\");\r\n } catch (error: any) {\r\n // Error should have a message\r\n assert.ok(error.message);\r\n assert.ok(error.message.length > 0);\r\n }\r\n });\r\n\r\n it(\"should handle conversion after previous error\", async () => {\r\n // First conversion fails\r\n try {\r\n await convertToString(\"{invalid}\", {\r\n inputFormat: \"json\",\r\n outputFormat: \"ndjson\",\r\n });\r\n } catch (error) {\r\n // Expected\r\n }\r\n\r\n // Second conversion should still work\r\n const result = await convertToString('{\"valid\":true}', {\r\n inputFormat: \"json\",\r\n outputFormat: \"ndjson\",\r\n });\r\n \r\n assert.ok(result);\r\n });\r\n });\r\n\r\n // ========== EDGE CASE COMBINATIONS ==========\r\n describe(\"Edge Case Combinations\", () => {\r\n it(\"should handle empty input with invalid format\", async () => {\r\n try {\r\n await convertToString(\"\", {\r\n inputFormat: \"invalid\" as any,\r\n outputFormat: \"json\",\r\n });\r\n assert.ok(true);\r\n } catch (error) {\r\n assert.ok(error);\r\n }\r\n });\r\n\r\n it(\"should handle corrupted data with streaming API\", async () => {\r\n const buddy = await ConvertBuddy.create({\r\n inputFormat: \"csv\",\r\n outputFormat: \"ndjson\",\r\n });\r\n\r\n try {\r\n const corrupted = new TextEncoder().encode('name,age\\n\"Alice,30');\r\n buddy.push(corrupted);\r\n buddy.finish();\r\n assert.ok(true);\r\n } catch (error) {\r\n assert.ok(error);\r\n }\r\n });\r\n\r\n it(\"should handle Unicode errors in large files\", async () => {\r\n // Create large file with invalid UTF-8 in the middle\r\n let data = \"name,age\\n\";\r\n for (let i = 0; i < 1000; i++) {\r\n data += `Alice${i},${i}\\n`;\r\n }\r\n \r\n const encoded = new TextEncoder().encode(data);\r\n // Corrupt a byte in the middle\r\n const corrupted = new Uint8Array(encoded);\r\n corrupted[encoded.length / 2] = 0xFF;\r\n\r\n try {\r\n await convert(corrupted, {\r\n inputFormat: \"csv\",\r\n outputFormat: \"ndjson\",\r\n });\r\n assert.ok(true);\r\n } catch (error) {\r\n assert.ok(error);\r\n }\r\n });\r\n });\r\n\r\n // ========== SAFETY GUARANTEES ==========\r\n describe(\"Safety Guarantees\", () => {\r\n it(\"should never crash on any input\", async () => {\r\n // Test with completely random data\r\n const randomData = new Uint8Array(1000);\r\n for (let i = 0; i < randomData.length; i++) {\r\n randomData[i] = Math.floor(Math.random() * 256);\r\n }\r\n\r\n try {\r\n await convert(randomData, {\r\n inputFormat: \"csv\",\r\n outputFormat: \"ndjson\",\r\n });\r\n assert.ok(true);\r\n } catch (error) {\r\n // Error is acceptable, crash is not\r\n assert.ok(error);\r\n }\r\n });\r\n\r\n it(\"should handle all printable ASCII characters\", async () => {\r\n let csv = \"name,value\\n\";\r\n for (let i = 32; i < 127; i++) {\r\n csv += `char${i},${String.fromCharCode(i)}\\n`;\r\n }\r\n\r\n try {\r\n const result = await convertToString(csv, {\r\n inputFormat: \"csv\",\r\n outputFormat: \"ndjson\",\r\n });\r\n assert.ok(result);\r\n } catch (error) {\r\n assert.ok(error);\r\n }\r\n });\r\n\r\n it(\"should handle all control characters\", async () => {\r\n let csv = \"name,value\\n\";\r\n for (let i = 0; i < 32; i++) {\r\n if (i !== 10 && i !== 13) { // Skip LF and CR\r\n csv += `char${i},${String.fromCharCode(i)}\\n`;\r\n }\r\n }\r\n\r\n try {\r\n const result = await convertToString(csv, {\r\n inputFormat: \"csv\",\r\n outputFormat: \"ndjson\",\r\n });\r\n assert.ok(result);\r\n } catch (error) {\r\n assert.ok(error);\r\n }\r\n });\r\n\r\n it(\"should never leak memory on errors\", async () => {\r\n const initialMem = process.memoryUsage().heapUsed;\r\n\r\n // Run many failing conversions\r\n for (let i = 0; i < 100; i++) {\r\n try {\r\n await convertToString(\"{invalid}\", {\r\n inputFormat: \"json\",\r\n outputFormat: \"ndjson\",\r\n });\r\n } catch (error) {\r\n // Expected\r\n }\r\n }\r\n\r\n if (global.gc) {\r\n global.gc();\r\n }\r\n\r\n const finalMem = process.memoryUsage().heapUsed;\r\n const memIncrease = (finalMem - initialMem) / (1024 * 1024);\r\n\r\n // Memory increase should be reasonable (< 10MB for 100 errors)\r\n assert.ok(memIncrease < 10, `Memory increased by ${memIncrease.toFixed(2)}MB`);\r\n });\r\n });\r\n});\r\n\r\nconsole.log(\"✓ Error Handling Test Suite loaded\");\r\nconsole.log(\" Run with: node --test tests/edge-cases/error-handling.test.ts\");\r\n"],"mappings":"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","names":[]}
@@ -0,0 +1,2 @@
1
+
2
+ export { }