Skip to content

Commit 6f80411

Browse files
committed
test(async): add batch processing tests for concurrent file parsing and generate-to-file
1 parent 5543ca3 commit 6f80411

2 files changed

Lines changed: 211 additions & 0 deletions

File tree

test/async.spec.js

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
'use strict';
2+
3+
const assert = require('assert');
4+
const csvToJsonAsync = require('../src/csvToJsonAsync');
5+
const index = require('../index');
6+
7+
describe('Async API testing', () => {
8+
describe('getJsonFromCsvAsync() with files', () => {
9+
it('should read and parse CSV file asynchronously', () => {
10+
return csvToJsonAsync.fieldDelimiter(';')
11+
.getJsonFromCsvAsync('test/resource/input_example.csv')
12+
.then(result => {
13+
assert.ok(Array.isArray(result));
14+
assert.ok(result.length > 0);
15+
// First row should have expected fields
16+
assert.ok(result[0].hasOwnProperty('firstName'));
17+
assert.ok(result[0].hasOwnProperty('lastName'));
18+
assert.strictEqual(result[0].firstName, 'Constantin');
19+
});
20+
});
21+
22+
it('should handle field delimiter in async mode', () => {
23+
return csvToJsonAsync.fieldDelimiter('~')
24+
.getJsonFromCsvAsync('test/resource/input_tilde_delimiter.csv')
25+
.then(result => {
26+
assert.ok(Array.isArray(result));
27+
assert.ok(result.length > 0);
28+
// Verify fields are parsed correctly with custom delimiter
29+
assert.strictEqual(result[0].firstName, 'Constantin');
30+
assert.strictEqual(result[0].lastName, 'Langsdon');
31+
});
32+
});
33+
34+
it('should reject on missing file', () => {
35+
return csvToJsonAsync.getJsonFromCsvAsync('nonexistent.csv')
36+
.then(() => {
37+
throw new Error('Should have rejected');
38+
})
39+
.catch(err => {
40+
// fs.promises.readFile errors are objects with code
41+
// fallback fs.readFile errors are Error instances
42+
assert.ok(err && (err.code === 'ENOENT' || err.message.includes('ENOENT')));
43+
});
44+
});
45+
});
46+
47+
describe('getJsonFromCsvAsync() with raw CSV strings', () => {
48+
beforeEach(() => {
49+
// Reset to default delimiter for raw string tests
50+
index.fieldDelimiter(';');
51+
});
52+
53+
it('should parse raw CSV string when options.raw=true', () => {
54+
const csvString = 'name;age;city\nAlice;30;New York\nBob;25;Boston';
55+
return csvToJsonAsync.getJsonFromCsvAsync(csvString, { raw: true })
56+
.then(result => {
57+
assert.ok(Array.isArray(result));
58+
assert.strictEqual(result.length, 2);
59+
assert.deepStrictEqual(result[0], {
60+
name: 'Alice',
61+
age: '30',
62+
city: 'New York'
63+
});
64+
assert.deepStrictEqual(result[1], {
65+
name: 'Bob',
66+
age: '25',
67+
city: 'Boston'
68+
});
69+
});
70+
});
71+
72+
it('should format values by type in raw mode', () => {
73+
const csvString = 'name;age;active\nAlice;30;true\nBob;25;false';
74+
return index.formatValueByType(true)
75+
.getJsonFromCsvAsync(csvString, { raw: true })
76+
.then(result => {
77+
assert.ok(Array.isArray(result));
78+
assert.strictEqual(result.length, 2);
79+
// Age should be number, active should be boolean
80+
assert.strictEqual(typeof result[0].age, 'number');
81+
assert.strictEqual(typeof result[0].active, 'boolean');
82+
assert.strictEqual(result[0].age, 30);
83+
assert.strictEqual(result[0].active, true);
84+
});
85+
});
86+
87+
it('should handle empty input with raw=true', () => {
88+
return csvToJsonAsync.getJsonFromCsvAsync('', { raw: true })
89+
.then(result => {
90+
assert.ok(Array.isArray(result));
91+
assert.strictEqual(result.length, 0);
92+
});
93+
});
94+
95+
it('should reject when input is null/undefined', () => {
96+
return Promise.all([
97+
index.getJsonFromCsvAsync(null, { raw: true })
98+
.then(() => { throw new Error('Should reject null'); })
99+
.catch(err => assert.ok(err instanceof Error)),
100+
index.getJsonFromCsvAsync(undefined, { raw: true })
101+
.then(() => { throw new Error('Should reject undefined'); })
102+
.catch(err => assert.ok(err instanceof Error))
103+
]);
104+
});
105+
});
106+
});

test/csvToJsonAsync.spec.js

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
'use strict';
22

33
const assert = require('assert');
4+
const fs = require('fs');
5+
const path = require('path');
46
const csvToJsonAsync = require('../src/csvToJsonAsync');
57
const index = require('../index');
68

@@ -42,6 +44,27 @@ describe('Async API testing', () => {
4244
assert.ok(err && (err.code === 'ENOENT' || err.message.includes('ENOENT')));
4345
});
4446
});
47+
48+
it('should handle UTF-16LE encoded CSV files in async processing', async () => {
49+
const testDir = path.join(__dirname, 'temp');
50+
if (!fs.existsSync(testDir)) fs.mkdirSync(testDir);
51+
const encodingFile = path.join(testDir, 'utf16le.csv');
52+
const csvContent = 'firstName;lastName\nJohn;Doe';
53+
54+
// Write content as UTF-16LE
55+
const buffer = Buffer.from(csvContent, 'utf16le');
56+
await fs.promises.writeFile(encodingFile, buffer);
57+
58+
try {
59+
const result = await csvToJsonAsync.encoding('utf16le').fieldDelimiter(';').getJsonFromCsvAsync(encodingFile);
60+
assert.ok(Array.isArray(result));
61+
assert.strictEqual(result.length, 1);
62+
assert.strictEqual(result[0].firstName, 'John');
63+
assert.strictEqual(result[0].lastName, 'Doe');
64+
} finally {
65+
if (fs.existsSync(encodingFile)) await fs.promises.unlink(encodingFile);
66+
}
67+
});
4568
});
4669

4770
describe('getJsonFromCsvAsync() with raw CSV strings', () => {
@@ -103,4 +126,86 @@ describe('Async API testing', () => {
103126
]);
104127
});
105128
});
129+
130+
describe('Batch processing multiple files (async)', () => {
131+
const testDir = path.join(__dirname, 'temp');
132+
133+
beforeAll(() => {
134+
if (!fs.existsSync(testDir)) fs.mkdirSync(testDir);
135+
});
136+
137+
afterAll(() => {
138+
if (fs.existsSync(testDir)) {
139+
fs.rmSync(testDir, { recursive: true, force: true });
140+
}
141+
});
142+
143+
it('should process multiple CSV files concurrently and return correct results', async () => {
144+
const fileA = path.join(testDir, 'batchA.csv');
145+
const fileB = path.join(testDir, 'batchB.csv');
146+
147+
const csvA = 'firstName;lastName\nAlice;Arden';
148+
const csvB = 'firstName;lastName\nBob;Baker';
149+
150+
await fs.promises.writeFile(fileA, csvA, 'utf8');
151+
await fs.promises.writeFile(fileB, csvB, 'utf8');
152+
153+
try {
154+
// ensure encoding and delimiter are set to defaults for these test files
155+
csvToJsonAsync.encoding('utf8').fieldDelimiter(';');
156+
157+
const [resA, resB] = await Promise.all([
158+
csvToJsonAsync.getJsonFromCsvAsync(fileA),
159+
csvToJsonAsync.getJsonFromCsvAsync(fileB)
160+
]);
161+
162+
assert.ok(Array.isArray(resA));
163+
assert.ok(Array.isArray(resB));
164+
assert.strictEqual(resA.length, 1);
165+
assert.strictEqual(resB.length, 1);
166+
assert.strictEqual(resA[0].firstName, 'Alice');
167+
assert.strictEqual(resA[0].lastName, 'Arden');
168+
assert.strictEqual(resB[0].firstName, 'Bob');
169+
assert.strictEqual(resB[0].lastName, 'Baker');
170+
} finally {
171+
if (fs.existsSync(fileA)) await fs.promises.unlink(fileA);
172+
if (fs.existsSync(fileB)) await fs.promises.unlink(fileB);
173+
}
174+
});
175+
176+
it('should generate JSON files for multiple inputs concurrently', async () => {
177+
const file1 = path.join(testDir, 'input1.csv');
178+
const file2 = path.join(testDir, 'input2.csv');
179+
const out1 = path.join(testDir, 'out1.json');
180+
const out2 = path.join(testDir, 'out2.json');
181+
182+
const csv1 = 'name;age\nCharlie;40';
183+
const csv2 = 'name;age\nDana;35';
184+
185+
await fs.promises.writeFile(file1, csv1, 'utf8');
186+
await fs.promises.writeFile(file2, csv2, 'utf8');
187+
188+
try {
189+
csvToJsonAsync.encoding('utf8').fieldDelimiter(';');
190+
191+
await Promise.all([
192+
csvToJsonAsync.generateJsonFileFromCsv(file1, out1),
193+
csvToJsonAsync.generateJsonFileFromCsv(file2, out2)
194+
]);
195+
196+
// read and validate outputs
197+
const outContent1 = JSON.parse(fs.readFileSync(out1, 'utf8'));
198+
const outContent2 = JSON.parse(fs.readFileSync(out2, 'utf8'));
199+
200+
assert.ok(Array.isArray(outContent1));
201+
assert.ok(Array.isArray(outContent2));
202+
assert.strictEqual(outContent1[0].name, 'Charlie');
203+
assert.strictEqual(String(outContent1[0].age), '40');
204+
assert.strictEqual(outContent2[0].name, 'Dana');
205+
assert.strictEqual(String(outContent2[0].age), '35');
206+
} finally {
207+
[file1, file2, out1, out2].forEach(f => { if (fs.existsSync(f)) fs.unlinkSync(f); });
208+
}
209+
});
210+
});
106211
});

0 commit comments

Comments
 (0)