adds more robust testing for complex cases

This commit is contained in:
mikesealey 2025-01-29 17:52:14 +00:00
parent 631448871e
commit 6a94aada19
2 changed files with 38 additions and 14 deletions

View File

@ -4,15 +4,10 @@ export async function jsonFromCsvString(csvString: string) {
const possibleDelimeters = [",", ";", ":", "|", "~", "\t", " "]
for (let i = 0; i < possibleDelimeters.length; i++) {
let numOfHeaders: number | undefined = undefined
let headers: string[] | undefined = undefined
let headerMismatch = false
try {
const castedWithEmptyValues = await csv({
ignoreEmpty: true,
delimiter: possibleDelimeters[i],
}).fromString(csvString)
// By default the csvtojson library casts empty values as empty strings. This
// is causing issues on conversion. ignoreEmpty will remove the key completly
// if empty, so creating this empty object will ensure we return the values
@ -28,18 +23,17 @@ export async function jsonFromCsvString(csvString: string) {
// If the number of columms in each row is different to
// the number of headers, this isn't the right delimiter
const columns = Object.keys(r)
if (numOfHeaders == null) {
numOfHeaders = columns.length
if (headers == null) {
headers = columns
}
if (numOfHeaders === 1 || numOfHeaders !== columns.length) {
if (headers.length === 1 || headers.length !== columns.length) {
headerMismatch = true
break
}
for (const [key] of Object.entries(r).filter(
([, value]) => value === ""
)) {
if (castedWithEmptyValues[i][key] === undefined) {
r[key] = null
for (const header of headers) {
if (r[header] === undefined || r[header] === "") {
r[header] = null
}
}
}

View File

@ -1,3 +1,4 @@
import { delimiter } from "path"
import { jsonFromCsvString } from "../csv"
describe("csv", () => {
@ -29,5 +30,34 @@ describe("csv", () => {
expect(Object.keys(r)).toEqual(["id", "optional", "title"])
)
})
const possibleDelimeters = [",", ";", ":", "|", "~", "\t", " "]
const csvArray = [
["id", "title"],
["1", "aaa"],
["2", "bbb"],
["3", "c ccc"],
["", ""],
[":5", "eee5:e"],
]
test.each(possibleDelimeters)(
"Should parse with delimiter %s",
async delimiter => {
const csvString = csvArray
.map(row => row.map(col => `"${col}"`).join(delimiter))
.join("\n")
const result = await jsonFromCsvString(csvString)
expect(result).toEqual([
{ id: "1", title: "aaa" },
{ id: "2", title: "bbb" },
{ id: "3", title: "c ccc" },
{ id: null, title: null },
{ id: ":5", title: "eee5:e" },
])
}
)
})
})