Skip to content

Commit

Permalink
fix: lost headers after broken lines (#151)
Browse files Browse the repository at this point in the history
* fix: strict false - broken header keys

* fix: do not replace global headers

* fix: if header exists object properties are set

* fix: move added properties to end

* fix: add missing informations
  • Loading branch information
aheissenberger authored Sep 29, 2020
1 parent dd5123b commit a72f822
Show file tree
Hide file tree
Showing 7 changed files with 117 additions and 6 deletions.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -251,9 +251,13 @@ Maximum number of bytes per row. An error is thrown if a line exeeds this value.
#### strict

Type: `Boolean`<br>
Default: `false`

If `true`, instructs the parser that the number of columns in each row must match
the number of `headers` specified.
the number of `headers` specified or throws an exception.
if `false`: the headers are mapped to the column index
less columns: any missing column in the middle will result in a wrong property mapping!
more columns: the aditional columns will create a "_"+index properties - eg. "_10":"value"

## Events

Expand Down
11 changes: 6 additions & 5 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -176,14 +176,15 @@ class CsvParser extends Transform {
}

writeRow (cells) {
if (this.headers === false || cells.length > this.headers.length) {
this.headers = cells.map((value, index) => index)
}
const headers = (this.headers === false) ? cells.map((value, index) => index) : this.headers

const row = cells.reduce((o, cell, index) => {
const header = this.headers[index]
if (header !== null) {
const header = headers[index]
if (header === null) return o // skip columns
if (header !== undefined) {
o[header] = cell
} else {
o[`_${index}`] = cell
}
return o
}, {})
Expand Down
4 changes: 4 additions & 0 deletions test/fixtures/strict-false-less-columns.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
a,b,c
1,2,3
4,5
6,7,8
4 changes: 4 additions & 0 deletions test/fixtures/strict-false-more-columns.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
a,b,c
1,2,3
4,5,6,7
8,9,10
57 changes: 57 additions & 0 deletions test/snapshots/strictNo.test.js.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Snapshot report for `test/strictNo.test.js`

The actual snapshot is saved in `strictNo.test.js.snap`.

Generated by [AVA](https://ava.li).

## strict: false - less columns

> first row
{
a: '1',
b: '2',
c: '3',
}

> broken row
{
a: '4',
b: '5',
}

> last row
{
a: '6',
b: '7',
c: '8',
}

## strict: false - more columns

> first row
{
a: '1',
b: '2',
c: '3',
}

> broken row
{
_3: '7',
a: '4',
b: '5',
c: '6',
}

> last row
{
a: '8',
b: '9',
c: '10',
}
Binary file added test/snapshots/strictNo.test.js.snap
Binary file not shown.
41 changes: 41 additions & 0 deletions test/strictNo.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
const test = require('ava')

const { collect } = require('./helpers/helper')

test.cb('strict: false - more columns', (t) => {
const verify = (err, lines) => {
const headersFirstLine = Object.keys(lines[0])
const headersBrokenLine = Object.keys(lines[1])
const headersLastLine = Object.keys(lines[2])
t.false(err, 'no err')
t.deepEqual(headersFirstLine, headersLastLine)
t.deepEqual(headersBrokenLine, ['a', 'b', 'c', '_3'])
t.snapshot(lines[0], 'first row')
t.snapshot(lines[1], 'broken row')
t.snapshot(lines[2], 'last row')
t.is(lines.length, 3, '3 rows')
t.is(headersBrokenLine.length, 4, '4 columns')
t.end()
}

collect('strict-false-more-columns', { strict: false }, verify)
})

test.cb('strict: false - less columns', (t) => {
const verify = (err, lines) => {
const headersFirstLine = Object.keys(lines[0])
const headersBrokenLine = Object.keys(lines[1])
const headersLastLine = Object.keys(lines[2])
t.false(err, 'no err')
t.deepEqual(headersFirstLine, headersLastLine)
t.deepEqual(headersBrokenLine, ['a', 'b'])
t.snapshot(lines[0], 'first row')
t.snapshot(lines[1], 'broken row')
t.snapshot(lines[2], 'last row')
t.is(lines.length, 3, '3 rows')
t.is(headersBrokenLine.length, 2, '2 columns')
t.end()
}

collect('strict-false-less-columns', { strict: false }, verify)
})

0 comments on commit a72f822

Please sign in to comment.