|
|
@ -1,12 +1,9 @@ |
|
|
|
// TODO: Add tests for unparse:
|
|
|
|
|
|
|
|
// If fields is omitted, write a CSV string without a header row
|
|
|
|
|
|
|
|
// If delimiter is omitted, choose comma by default
|
|
|
|
|
|
|
|
// If data is omitted, do nothing... maybe if fields IS specified, write just the header row?
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var RECORD_SEP = String.fromCharCode(30); |
|
|
|
var RECORD_SEP = String.fromCharCode(30); |
|
|
|
var UNIT_SEP = String.fromCharCode(31); |
|
|
|
var UNIT_SEP = String.fromCharCode(31); |
|
|
|
|
|
|
|
|
|
|
|
var TESTS = [ |
|
|
|
|
|
|
|
|
|
|
|
// Tests for Papa.parse() function (CSV to JSON)
|
|
|
|
|
|
|
|
var PARSE_TESTS = [ |
|
|
|
{ |
|
|
|
{ |
|
|
|
input: 'A,b,c', |
|
|
|
input: 'A,b,c', |
|
|
|
description: "One row", |
|
|
|
description: "One row", |
|
|
@ -313,10 +310,10 @@ var TESTS = [ |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
}, |
|
|
|
{ |
|
|
|
{ |
|
|
|
input: 'a,b,c\r\n,e,f', |
|
|
|
input: 'a,b,\r\nd,e,f', |
|
|
|
description: "First field of a line is empty", |
|
|
|
description: "Last field of a line is empty", |
|
|
|
expected: { |
|
|
|
expected: { |
|
|
|
data: [['a', 'b', 'c'], ['', 'e', 'f']], |
|
|
|
data: [['a', 'b', ''], ['d', 'e', 'f']], |
|
|
|
errors: [] |
|
|
|
errors: [] |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
}, |
|
|
@ -416,4 +413,152 @@ var TESTS = [ |
|
|
|
errors: [] |
|
|
|
errors: [] |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Tests for Papa.unparse() function (JSON to CSV)
|
|
|
|
|
|
|
|
var UNPARSE_TESTS = [ |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
description: "A simple row", |
|
|
|
|
|
|
|
notes: "Comma should be default delimiter", |
|
|
|
|
|
|
|
input: [['A', 'b', 'c']], |
|
|
|
|
|
|
|
expected: 'A,b,c' |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
description: "Two rows", |
|
|
|
|
|
|
|
input: [['A', 'b', 'c'], ['d', 'E', 'f']], |
|
|
|
|
|
|
|
expected: 'A,b,c\r\nd,E,f' |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
description: "Data with quotes", |
|
|
|
|
|
|
|
input: [['a', '"b"', 'c'], ['"d"', 'e', 'f']], |
|
|
|
|
|
|
|
expected: 'a,"""b""",c\r\n"""d""",e,f' |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
description: "Data with newlines", |
|
|
|
|
|
|
|
input: [['a', 'b\nb', 'c'], ['d', 'e', 'f\r\nf']], |
|
|
|
|
|
|
|
expected: 'a,"b\nb",c\r\nd,e,"f\r\nf"' |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
description: "Array of objects (header row)", |
|
|
|
|
|
|
|
input: [{ "Col1": "a", "Col2": "b", "Col3": "c" }, { "Col1": "d", "Col2": "e", "Col3": "f" }], |
|
|
|
|
|
|
|
expected: 'Col1,Col2,Col3\r\na,b,c\r\nd,e,f' |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
description: "With header row, missing a field in a row", |
|
|
|
|
|
|
|
input: [{ "Col1": "a", "Col2": "b", "Col3": "c" }, { "Col1": "d", "Col3": "f" }], |
|
|
|
|
|
|
|
expected: 'Col1,Col2,Col3\r\na,b,c\r\nd,,f' |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
description: "With header row, with extra field in a row", |
|
|
|
|
|
|
|
notes: "Extra field should be ignored; first object in array dictates header row", |
|
|
|
|
|
|
|
input: [{ "Col1": "a", "Col2": "b", "Col3": "c" }, { "Col1": "d", "Col2": "e", "Extra": "g", "Col3": "f" }], |
|
|
|
|
|
|
|
expected: 'Col1,Col2,Col3\r\na,b,c\r\nd,e,f' |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
description: "Specifying column names and data separately", |
|
|
|
|
|
|
|
input: { fields: ["Col1", "Col2", "Col3"], data: [["a", "b", "c"], ["d", "e", "f"]] }, |
|
|
|
|
|
|
|
expected: 'Col1,Col2,Col3\r\na,b,c\r\nd,e,f' |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
description: "Specifying column names only (no data)", |
|
|
|
|
|
|
|
notes: "Papa should add a data property that is an empty array to prevent errors (no copy is made)", |
|
|
|
|
|
|
|
input: { fields: ["Col1", "Col2", "Col3"] }, |
|
|
|
|
|
|
|
expected: 'Col1,Col2,Col3' |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
description: "Specifying data only (no field names), improperly", |
|
|
|
|
|
|
|
notes: "A single array for a single row is wrong, but it can be compensated.<br>Papa should add empty fields property to prevent errors.", |
|
|
|
|
|
|
|
input: { data: ["abc", "d", "ef"] }, |
|
|
|
|
|
|
|
expected: 'abc,d,ef' |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
description: "Specifying data only (no field names), properly", |
|
|
|
|
|
|
|
notes: "An array of arrays, even if just a single row.<br>Papa should add empty fields property to prevent errors.", |
|
|
|
|
|
|
|
input: { data: [["a", "b", "c"]] }, |
|
|
|
|
|
|
|
expected: 'a,b,c' |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
description: "Custom delimiter (semicolon)", |
|
|
|
|
|
|
|
input: [['A', 'b', 'c'], ['d', 'e', 'f']], |
|
|
|
|
|
|
|
config: { delimiter: ';' }, |
|
|
|
|
|
|
|
expected: 'A;b;c\r\nd;e;f' |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
description: "Custom delimiter (tab)", |
|
|
|
|
|
|
|
input: [['Ab', 'cd', 'ef'], ['g', 'h', 'ij']], |
|
|
|
|
|
|
|
config: { delimiter: '\t' }, |
|
|
|
|
|
|
|
expected: 'Ab\tcd\tef\r\ng\th\tij' |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
description: "Custom delimiter (ASCII 30)", |
|
|
|
|
|
|
|
input: [['a', 'b', 'c'], ['d', 'e', 'f']], |
|
|
|
|
|
|
|
config: { delimiter: RECORD_SEP }, |
|
|
|
|
|
|
|
expected: 'a'+RECORD_SEP+'b'+RECORD_SEP+'c\r\nd'+RECORD_SEP+'e'+RECORD_SEP+'f' |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
description: "Bad delimiter (\\n)", |
|
|
|
|
|
|
|
notes: "Should default to comma", |
|
|
|
|
|
|
|
input: [['a', 'b', 'c'], ['d', 'e', 'f']], |
|
|
|
|
|
|
|
config: { delimiter: '\n' }, |
|
|
|
|
|
|
|
expected: 'a,b,c\r\nd,e,f' |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
description: "Custom line ending (\\r)", |
|
|
|
|
|
|
|
input: [['a', 'b', 'c'], ['d', 'e', 'f']], |
|
|
|
|
|
|
|
config: { newline: '\r' }, |
|
|
|
|
|
|
|
expected: 'a,b,c\rd,e,f' |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
description: "Custom line ending (\\n)", |
|
|
|
|
|
|
|
input: [['a', 'b', 'c'], ['d', 'e', 'f']], |
|
|
|
|
|
|
|
config: { newline: '\n' }, |
|
|
|
|
|
|
|
expected: 'a,b,c\nd,e,f' |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
description: "Custom, but strange, line ending ($)", |
|
|
|
|
|
|
|
input: [['a', 'b', 'c'], ['d', 'e', 'f']], |
|
|
|
|
|
|
|
config: { newline: '$' }, |
|
|
|
|
|
|
|
expected: 'a,b,c$d,e,f' |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
description: "Force quotes around all fields", |
|
|
|
|
|
|
|
input: [['a', 'b', 'c'], ['d', 'e', 'f']], |
|
|
|
|
|
|
|
config: { quotes: true }, |
|
|
|
|
|
|
|
expected: '"a","b","c"\r\n"d","e","f"' |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
description: "Force quotes around all fields (with header row)", |
|
|
|
|
|
|
|
input: [{ "Col1": "a", "Col2": "b", "Col3": "c" }, { "Col1": "d", "Col2": "e", "Col3": "f" }], |
|
|
|
|
|
|
|
config: { quotes: true }, |
|
|
|
|
|
|
|
expected: '"Col1","Col2","Col3"\r\n"a","b","c"\r\n"d","e","f"' |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
description: "Force quotes around certain fields only", |
|
|
|
|
|
|
|
input: [['a', 'b', 'c'], ['d', 'e', 'f']], |
|
|
|
|
|
|
|
config: { quotes: [0, 2] }, |
|
|
|
|
|
|
|
expected: '"a",b,"c"\r\n"d",e,"f"' |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
description: "Force quotes around certain fields only (with header row)", |
|
|
|
|
|
|
|
input: [{ "Col1": "a", "Col2": "b", "Col3": "c" }, { "Col1": "d", "Col2": "e", "Col3": "f" }], |
|
|
|
|
|
|
|
config: { quotes: [0, 2] }, |
|
|
|
|
|
|
|
expected: '"Col1",Col2,"Col3"\r\n"a",b,"c"\r\n"d",e,"f"' |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
description: "Empty input", |
|
|
|
|
|
|
|
input: [], |
|
|
|
|
|
|
|
expected: '' |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
description: "Mismatched field counts in rows", |
|
|
|
|
|
|
|
input: [['a', 'b', 'c'], ['d', 'e'], ['f']], |
|
|
|
|
|
|
|
expected: 'a,b,c\r\nd,e\r\nf' |
|
|
|
|
|
|
|
} |
|
|
|
]; |
|
|
|
]; |